ES6中基于ID合并数组并拼接子数组的实现需求问询
实现方案
没问题,这有一个完全符合你需求的实现方案,我会把逻辑拆解清楚:
首先明确核心规则:
- 按
id唯一分组,最终每个id仅出现一次 - 同名非数组属性:后续数据覆盖之前的(比如同id的
salary,取最后一条的数值) - 同名数组属性:将所有对应数组合并拼接(可选去重)
代码实现
const persons = [ { id: 1, name: 'Peter', job: 'Programmer' }, { id: 2, name: 'Jeff', job: 'Architect' }, ]; const salaries = [ { id: 1, salary: 3000, departments: ['A', 'B'] }, { id: 1, salary: 4000, departments: ['A', 'C'] }, { id: 2, salary: 4000, departments: ['C', 'D'] }, ]; // 合并两个数据源为一个数组,统一处理 const combinedData = [...persons, ...salaries]; // 核心合并逻辑 const mergedResult = Object.values(combinedData.reduce((acc, currentItem) => { const { id } = currentItem; // 初始化当前id的条目(如果还不存在) if (!acc[id]) { acc[id] = { ...currentItem }; return acc; } // 遍历当前条目的每个属性,按规则合并 for (const key in currentItem) { if (!currentItem.hasOwnProperty(key)) continue; if (key === 'id') continue; // id作为分组键,无需处理 const currentValue = currentItem[key]; const existingValue = acc[id][key]; // 处理数组属性:拼接 if (Array.isArray(currentValue) && Array.isArray(existingValue)) { // 如果你需要去重,可以替换成下面这行: // acc[id][key] = [...new Set([...existingValue, ...currentValue])]; acc[id][key] = [...existingValue, ...currentValue]; } else { // 处理非数组属性:替换(后续值覆盖前面的值) acc[id][key] = currentValue; } } return acc; }, {})); // 输出结果 console.log(mergedResult);
逻辑说明
- 合并数据源:先把
persons和salaries合并成一个数组,这样我们可以用一次遍历完成所有处理 - 分组合并:用
reduce方法以id为键构建临时对象,每个键对应一个合并后的条目 - 属性处理规则:
- 首次遇到某个
id时,直接把当前条目存入临时对象 - 再次遇到相同
id时,逐个遍历属性:- 如果是数组类型,就把当前数组拼接到已有数组的后面(如果需要去重,用
Set处理即可) - 如果是非数组类型,直接用当前值覆盖已有值(符合你要求的“替换”逻辑)
- 如果是数组类型,就把当前数组拼接到已有数组的后面(如果需要去重,用
- 首次遇到某个
- 转换为数组:最后用
Object.values把临时对象转换成数组,得到最终的合并结果
输出结果
运行代码后,你会得到以下合并后的数组:
[ { id: 1, name: 'Peter', job: 'Programmer', salary: 4000, // 后面的4000替换了前面的3000 departments: ['A', 'B', 'A', 'C'] // 两个departments数组合并 }, { id: 2, name: 'Jeff', job: 'Architect', salary: 4000, departments: ['C', 'D'] } ]
如果开启了数组去重的注释,id=1的departments会变成['A', 'B', 'C']
内容的提问来源于stack exchange,提问作者Nibor
相关产品推荐
相关产品推荐

