
本文介绍使用 JavaScript 的 reduce() 方法高效合并具有相同键值的对象数组,并将对应嵌套数组(如 worksSummaryDetailsObj)自动拼接去重,避免常见错误(如浅拷贝误用或 Set 误处理嵌套结构)。
本文介绍使用 javascript 的 `reduce()` 方法高效合并具有相同键值的对象数组,并将对应嵌套数组(如 `workssummarydetailsobj`)自动拼接去重,避免常见错误(如浅拷贝误用或 set 误处理嵌套结构)。
在实际开发中,我们常遇到需要按某个字段(例如 year)对对象数组进行分组聚合的场景。原始数据中可能存在多个同一年份的条目,每个条目都携带一个 worksSummaryDetailsObj 数组——目标是将同一年份的所有条目合并为一项,并将其 worksSummaryDetailsObj 数组合并(非去重,而是追加),形成结构清晰、无重复逻辑的汇总结果。
直接使用 Set + map + filter(如提问者尝试的方式)容易出错:Set 对对象数组无效(因引用不同被视为不同元素),且 filter 返回的是完整对象而非仅需合并的数组字段,导致嵌套结构混乱或内存泄漏风险。
✅ 推荐解法:使用 reduce() 构建以 year 为键的哈希表,再通过 Object.values() 提取最终结果:
const merged = Object.values(
worksSummaryDetailsArr.reduce((acc, item) => {
const { year, worksSummaryDetailsObj } = item;
if (!acc[year]) {
// 首次出现该年份:直接存入深拷贝后的初始项(注意:若需深拷贝整个对象,此处应谨慎)
acc[year] = { year, worksSummaryDetailsObj: [...worksSummaryDetailsObj] };
} else {
// 已存在:合并 worksSummaryDetailsObj 数组(使用扩展运算符实现浅层扁平拼接)
acc[year].worksSummaryDetailsObj = [
...acc[year].worksSummaryDetailsObj,
...worksSummaryDetailsObj
];
}
return acc;
}, {})
);
? 关键说明:
- acc 是一个普通对象(非 Map),以 year 为属性名,值为合并后的对象;
- 使用 ...acc[year].worksSummaryDetailsObj 确保每次都是新数组引用,避免意外的副作用;
- Object.values() 自动忽略原型链属性,安全提取所有归并后的年度对象;
- 此方案时间复杂度为 O(n),空间复杂度为 O(k),其中 k 是唯一年份数量,性能优异且语义清晰。
⚠️ 注意事项:
- 若 worksSummaryDetailsObj 中的对象需深度去重(而非简单拼接),应在合并后额外调用 filter() 或 Map 去重逻辑;
- 若原始数据中 year 可能为 undefined 或非字符串/数字类型,请先做类型校验(如 typeof year === 'number' && !isNaN(year));
- 不建议在 reduce 回调中直接修改原对象(如 item.worksSummaryDetailsObj.push(...)),这会污染源数据。
最终输出 merged 即为结构规整、按年份聚合完成的数组,完全符合预期格式,可直接用于渲染或后续计算。










