map+reduce能天然覆盖更新,因map.set()遇重复key自动替换旧值,reduce按序处理使后项覆盖先项;基础写法用item.id作key直接set,进阶可自定义合并逻辑,注意key需稳定且避免用对象/数组。

用 reduce 配合 Map 实现去重并覆盖更新,核心是:每次遍历用当前项的唯一键(如 id)作为 Map 的 key,直接 set 当前值——后出现的同 key 项自然覆盖前面的。
为什么 Map + reduce 能天然支持覆盖更新
Map.prototype.set(key, value) 不会报错,重复 key 时自动替换旧值。而 reduce 按数组顺序逐个处理,所以“后出现的相同 key 数据”会覆盖“先出现的”,逻辑清晰、无副作用。
基础写法:按 id 覆盖去重
假设数据是对象数组,以 id 为唯一标识:
const list = [
{ id: 1, name: 'Alice', score: 85 },
{ id: 2, name: 'Bob', score: 90 },
{ id: 1, name: 'Alicia', score: 92 }, // 覆盖上一个 id=1
{ id: 3, name: 'Cindy', score: 88 }
];
const uniqueMap = list.reduce((map, item) => {
map.set(item.id, item); // 直接 set,自动覆盖
return map;
}, new Map());
// 转回数组(可选)
const result = Array.from(uniqueMap.values());
// → [{ id: 1, name: 'Alicia', score: 92 }, { id: 2, name: 'Bob', score: 90 }, { id: 3, name: 'Cindy', score: 88 }]
进阶:自定义覆盖逻辑(比如只更新部分字段)
如果不想完全替换对象,而是合并或有选择地更新(如只更新 score,保留原 name),可在 reduce 中加判断:
const uniqueMap = list.reduce((map, item) => {
if (map.has(item.id)) {
// 获取已有项,仅更新特定字段
const existing = map.get(item.id);
map.set(item.id, { ...existing, score: item.score });
} else {
map.set(item.id, item);
}
return map;
}, new Map());
注意事项
- 确保 key 是稳定且可比较的(推荐用字符串/数字;避免用对象或数组作 key)
- 如果原始数组顺序重要,且希望“保留首次出现的”而非“最后出现的”,就把
reduce换成reduceRight,或改用forEach+!map.has(key)判断 -
Map保持插入顺序,Array.from(map.values())得到的数组顺序 = 最后一次成功set的顺序(即后出现的覆盖项排在它首次被设为 key 的位置)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











