
本文介绍使用 JavaScript reduce() 和对象累加器高效合并按 year 字段分组的数组对象,将重复年份对应的 worksSummaryDetailsObj 数组合并为单一扁平数组。
本文介绍使用 javascript `reduce()` 和对象累加器高效合并按 `year` 字段分组的数组对象,将重复年份对应的 `workssummarydetailsobj` 数组合并为单一扁平数组。
在实际开发中,我们常遇到需要按某个字段(如 year)对对象数组进行“分组+聚合”的场景:相同键值的对象需合并,其嵌套数组字段则需拼接而非覆盖。原始数据中存在多个 year: 2021 或 year: 2022 的条目,目标是将其归并为唯一项,并将所有同年的 worksSummaryDetailsObj 数组合并成一个不重复、顺序保留的大数组。
推荐解法是使用 Array.prototype.reduce() 配合普通对象作为累加器(hash map),以 year 为键缓存已处理项:
const merged = Object.values(
worksSummaryDetailsArr.reduce((acc, item) => {
if (!acc[item.year]) {
// 首次遇到该年份:直接存入
acc[item.year] = { ...item };
} else {
// 已存在:合并 worksSummaryDetailsObj 数组
acc[item.year] = {
year: item.year,
worksSummaryDetailsObj: [
...acc[item.year].worksSummaryDetailsObj,
...item.worksSummaryDetailsObj
]
};
}
return acc;
}, {})
);✅ 关键优势:
- 时间复杂度 O(n),仅遍历一次原数组;
- 语义清晰,逻辑直观,避免嵌套 filter + map 带来的多次遍历与引用混淆;
- 使用展开运算符(...)确保数组浅拷贝合并,不污染原始数据。
⚠️ 注意事项:
- 此方案假设 worksSummaryDetailsObj 始终为数组类型,若存在 undefined 或非数组值,建议预先校验:
const safeConcat = (a, b) => Array.isArray(a) && Array.isArray(b) ? [...a, ...b] : [...(Array.isArray(a) ? a : []), ...(Array.isArray(b) ? b : [])];
- 若需去重(即合并后剔除 worksSummaryDetailsObj 中完全相同的子对象),需额外实现深比较或基于唯一 ID 过滤,本例未涉及该需求;
- Object.values() 返回结果顺序不保证与年份数值顺序一致(如 2020, 2021, 2022),如需严格升序,后续可链式调用 .sort((a, b) => a.year - b.year)。
最终输出为结构规整的新数组,每个 year 唯一,对应 worksSummaryDetailsObj 包含该年所有原始子项,满足业务聚合诉求。

















