javascript中用reduce对对象数组去重需以set缓存唯一键,按单字段(如id)或多字段组合(如name+age)生成key,首次出现保留、重复跳过;覆盖式去重则用findindex替换已存在项。

JavaScript 中用 reduce 对对象数组去重,核心是利用一个临时对象(或 Map)记录已出现的唯一标识值,再逐个判断是否跳过重复项。关键在于明确“去重依据”——比如 id、name 或多个字段组合。
根据单个字段(如 id)去重
这是最常见场景。用 reduce 累积结果数组,同时用普通对象或 Set 缓存已见过的 id:
const list = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 1, name: 'Alice2' }, // 重复 id
{ id: 3, name: 'Charlie' }
];
const uniqueById = list.reduce((acc, item) => {
if (!acc.seen.has(item.id)) {
acc.seen.add(item.id);
acc.result.push(item);
}
return acc;
}, { seen: new Set(), result: [] }).result;
// 结果:[{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }]
- 用
{ seen: new Set(), result: [] }作为初始累加器,避免污染外部变量 -
Set查找时间复杂度为 O(1),比用普通对象if (!acc.seen[item.id])更安全(避免原型链干扰) - 保留首次出现的对象,后续同 id 的被跳过
根据多个字段组合去重(如 name + age)
当需要基于多个属性判断唯一性时,可生成联合键(字符串),再用 Set 记录:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
const people = [
{ name: 'Tom', age: 25 },
{ name: 'Jerry', age: 30 },
{ name: 'Tom', age: 25 }, // 完全重复
{ name: 'Tom', age: 26 }
];
const uniqueByComposite = people.reduce((acc, item) => {
const key = `${item.name}|${item.age}`;
if (!acc.seen.has(key)) {
acc.seen.add(key);
acc.result.push(item);
}
return acc;
}, { seen: new Set(), result: [] }).result;
- 分隔符(如
|)要确保不会出现在字段值中;更稳妥可用JSON.stringify([item.name, item.age]) - 注意字段类型一致性(如 age 是数字还是字符串),避免
'25'和25被判为不同
用 reduce 实现“覆盖式”去重(保留最后一次)
如果希望相同 key 的对象以**后出现的为准**(即覆盖前面的),只需调整判断逻辑顺序:
const list = [
{ id: 1, score: 80 },
{ id: 2, score: 90 },
{ id: 1, score: 95 } // 覆盖前一个 id=1
];
const latestById = list.reduce((acc, item) => {
const existsIndex = acc.result.findIndex(x => x.id === item.id);
if (existsIndex > -1) {
acc.result[existsIndex] = item; // 替换
} else {
acc.result.push(item);
}
return acc;
}, { result: [] }).result;
- 用
findIndex定位已存在项,直接替换,不依赖额外缓存结构 - 性能略低于 Set 方案(O(n²)),但逻辑直观,适合小数据量
注意事项与替代建议
reduce 写法灵活但可读性易下降。实际项目中可权衡以下点:
- 去重逻辑复杂时,先用
Map预处理(new Map(list.map(x => [x.id, x])))再取values(),更简洁 - IE 不支持
Set或findIndex,需 polyfill 或改用 for 循环 - 避免在
reduce中直接修改原数组或外部变量,保持函数纯度
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










