按id合并对象数组的核心是分组加属性级合并,需依业务定制规则;常用reduce分组后处理,也可用map提升语义清晰度与键类型兼容性,并应封装为支持自定义策略的复用函数,同时注意id类型统一、空值判断及数组去重等边界情况。

直接按 ID 合并对象数组,核心是“分组 + 合并”。关键不是简单去重,而是把相同 id 的对象属性合并(比如数值累加、字符串拼接、数组合并等),需根据业务逻辑定制合并规则。
用 reduce 分组再处理
最常用且灵活的方式:先用 reduce 按 id 分组,再对每组内的对象做属性级合并。
- 初始化一个空对象作为 accumulator,以
id为键存储分组结果 - 遍历原数组,对每个对象检查是否已存在同 id 条目;若存在,则按需合并属性;若不存在,则直接存入
- 最后用
Object.values()提取所有合并后的对象
示例(数值字段累加,字符串字段用逗号连接):
const list = [
{ id: 1, name: 'Alice', score: 85, tags: ['js'] },
{ id: 2, name: 'Bob', score: 90, tags: ['html'] },
{ id: 1, name: 'Alice', score: 15, tags: ['css'] }
];
const merged = Object.values(
list.reduce((acc, item) => {
const exist = acc[item.id];
if (exist) {
exist.score += item.score; // 数值累加
exist.tags = [...exist.tags, ...item.tags]; // 数组合并
// name 不变,或可设为首次出现的值
} else {
acc[item.id] = { ...item };
}
return acc;
}, {})
);
// 结果:[{ id: 1, name: 'Alice', score: 100, tags: ['js','css'] }, { id: 2, name: 'Bob', score: 90, tags: ['html'] }]
用 Map 实现更清晰的分组逻辑
相比普通对象,Map 更适合处理可能含非字符串 key 或需稳定遍历顺序的场景,语义也更明确。
- 创建
Map,key 为id,value 为该 id 对应的合并后对象 - 遍历时用
map.get(id)判断是否存在,存在则合并,否则 set 新对象 - 最后用
[...map.values()]转为数组
封装成可复用函数
把合并逻辑抽离为函数,支持传入自定义合并策略,提高复用性。
- 参数包括原始数组、id 键名、各字段的合并函数(如
(a, b) => a + b或(a, b) => [...new Set([...a, ...b])]) - 对每个字段单独判断:若未指定策略,默认保留第一个值;若指定了,就调用对应函数
- 避免硬编码字段名,让函数更通用
注意边界情况
实际使用中容易忽略但影响结果的点:
-
id类型不一致(如字符串'1'和数字1)会导致分组失败,建议统一转为字符串或数字 - 某些字段可能为
null或undefined,合并前需做空值判断 - 数组类字段合并时要注意去重或顺序,避免重复项堆积
- 如果需要深合并(嵌套对象),需额外递归处理,不能只靠展开运算符
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











