用 reduce 配合 Map 可高效去重并保留最后一次出现的记录,核心是利用 Map.set(key, value) 的自动覆盖特性;以唯一字段(如 id)为 key、整条对象为 value,重复 key 时后值覆盖前值,最后调用 Array.from(map.values()) 转为数组。

用 reduce 配合 Map 去重并保留最后一次出现的记录,关键是利用 Map.set(key, value) 的覆盖特性:重复设同一个 key 时,新值会自动替换旧值,天然保留最后赋值的那个。
核心思路:用唯一字段作 Map 的 key,整条记录作 value
假设数组元素是对象,需按某个属性(如 id)去重:
-
reduce遍历数组,每轮把当前项的id作为 key、当前对象作为 value 存入Map - 遇到相同
id时,Map.set()自动覆盖,后出现的对象“赢” - 最后用
Map.values()转成数组即可
代码示例(保留最后出现的 id 对应对象)
JavaScript
const list = [
{ id: 1, name: 'Alice', time: '08:00' },
{ id: 2, name: 'Bob', time: '09:00' },
{ id: 1, name: 'Alicia', time: '10:00' }, // 同 id,但后出现
{ id: 3, name: 'Charlie', time: '11:00' }
];
const uniqueLast = list.reduce((map, item) => {
map.set(item.id, item); // 直接 set,自动覆盖
return map;
}, new Map());
const result = Array.from(uniqueLast.values());
// → [{ id: 1, name: 'Alicia', time: '10:00' },
// { id: 2, name: 'Bob', time: '09:00' },
// { id: 3, name: 'Charlie', time: '11:00' }]
如果需要按多个字段组合去重
把多个字段拼成字符串 key 即可,例如按 id 和 type 联合去重:
立即学习“Java免费学习笔记(深入)”;
- key 改为
`${item.id}-${item.type}`(确保分隔符不会在字段中出现) - 或更稳妥地用
JSON.stringify([item.id, item.type]) - 其余逻辑完全一致
对比 filter + indexOf 的局限性
filter((x, i) => list.findIndex(y => y.id === x.id) === i) 这类写法默认保留第一次,要改“保留最后一次”就得倒序处理再反转,既低效又绕。而 Map + reduce 一次正向遍历就搞定,语义清晰、性能好、无副作用。


















