reduce去重核心是按指定字段(如id)以对象为累加器、属性值为key实现首次/末次保留或字段合并;需注意key合法性、引用类型陷阱及多字段组合技巧。

用 reduce 去重,核心是把“相同属性值”的对象归到同一个键下,再提取唯一项——不是简单删重复元素,而是按指定字段(如 id、name)保留首次或最后一次出现的记录。
按某个字段去重(保留第一个)
适合需要“首次出现优先”的场景,比如避免覆盖初始配置。
原理:用空对象作累加器,以目标属性为 key 存储整个对象;遍历时若 key 不存在才存入,自然跳过后续重复项。
const list = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 1, name: 'Alice Updated' },
{ id: 3, name: 'Charlie' }
];
const uniqueById = list.reduce((acc, item) => {
if (!acc[item.id]) {
acc[item.id] = item;
}
return acc;
}, {});
// 转回数组
const result = Object.values(uniqueById);
// [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }]
按某个字段去重(保留最后一个)
适合“后写入优先”逻辑,比如日志合并、状态更新。
只需去掉判断条件,每次都覆盖:
const result = Object.values(
list.reduce((acc, item) => {
acc[item.id] = item; // 直接赋值,后出现的覆盖前一个
return acc;
}, {})
);
去重并合并其他字段(如累加数量)
不止去重,还要聚合数据,比如合并相同商品的销量:
const orders = [
{ sku: 'A001', qty: 2 },
{ sku: 'A002', qty: 5 },
{ sku: 'A001', qty: 3 }
];
const merged = Object.values(
orders.reduce((acc, item) => {
const existing = acc[item.sku];
if (existing) {
acc[item.sku] = {
...existing,
qty: existing.qty + item.qty
};
} else {
acc[item.sku] = { ...item };
}
return acc;
}, {})
);
// [{ sku: 'A001', qty: 5 }, { sku: 'A002', qty: 5 }]
注意点和常见坑
- 属性值必须可作为对象 key:数字、字符串、布尔值可以;对象、数组、undefined、NaN 不行(会转成字符串,导致误判)
-
慎用引用类型字段去重:比如用
user对象做 key,实际是[object Object],全变成同一个 key -
想按多个字段组合去重?拼成唯一字符串 key,例如:
`${item.category}-${item.type}` -
原始数组含 null/undefined?先用
filter(Boolean)过滤,避免访问.id报错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











