map 本身不直接去重数组,但可借助其 o(1) 查找特性,以对象指定属性为键实现按属性去重,保留首次出现项;需提前创建 map 并配合 reduce 或 for 循环,避免 filter 内重复新建。

JavaScript 中 Map 本身不直接“去重数组”,但可以借助它高效地根据对象的某个属性(如 id、name)作为键,实现对复杂对象数组的去重——本质是“保留首次出现的、按某属性唯一”的对象。
用 Map 存储已见的属性值,过滤重复项
核心思路:遍历数组,以对象的指定属性(如 item.id)为 key 存入 Map;若该 key 未存在,才将当前对象加入结果数组,并在 Map 中标记已见。
✅ 推荐写法(简洁、可读、无副作用):
const arr = [
{ id: 1, name: 'Alice', dept: 'HR' },
{ id: 2, name: 'Bob', dept: 'IT' },
{ id: 1, name: 'Alice2', dept: 'Finance' }, // id 重复
{ id: 3, name: 'Charlie', dept: 'IT' }
];
const uniqueById = arr.filter((item, _, self) => {
const map = new Map();
return !map.has(item.id) && map.set(item.id, true);
});
// ❌ 错误!map 每次 filter 都新建,不起作用
⚠️ 上面写法有问题 —— Map 在每次回调中都重新创建,无法累积状态。正确做法是**提前创建 Map,配合 reduce 或 for 循环**:
- 用
reduce+ Map(推荐):
const uniqueById = arr.reduce((acc, item) => {
if (!acc.map.has(item.id)) {
acc.map.set(item.id, true);
acc.result.push(item);
}
return acc;
}, { map: new Map(), result: [] }).result;
- 更清晰的 for 循环写法(易理解、性能好):
const seen = new Map();
const uniqueById = [];
for (const item of arr) {
if (!seen.has(item.id)) {
seen.set(item.id, true);
uniqueById.push(item);
}
}
封装成可复用函数,支持任意属性名
把逻辑抽成函数,便于多次调用、更换去重字段(如按 name 或 email):
function uniqBy(arr, key) {
const seen = new Map();
return arr.filter(item => {
const value = typeof key === 'function' ? key(item) : item[key];
if (seen.has(value)) return false;
seen.set(value, true);
return true;
});
}
// 使用示例
const uniqueByName = uniqBy(arr, 'name'); // 按 name 去重
const uniqueByEmail = uniqBy(users, 'email');
const uniqueByCustom = uniqBy(arr, item => `${item.name}-${item.dept}`); // 组合键
注意:Map 的 key 对象引用 vs 基础值
Map 的键支持任意类型,但要注意:
- 数字、字符串、布尔等基础类型会自动转换并正确比较(
1和'1'是不同 key); - 若用对象/数组作 key(如
{id: 1}),每次新建都是不同引用,无法去重——所以**务必提取原始属性值(如item.id)作为 key**; - NaN 可作为 Map key,且能正确识别(与 Object 不同)。
对比其他方法(Set + map / filter + indexOf)
为什么推荐 Map 而不是 Set?
-
Set只能存完整对象或字符串,不能直接“按属性去重”;若先arr.map(x => x.id)再用 Set 去重,就丢失了原对象; -
filter + indexOf时间复杂度 O(n²),大数据量慢;Map 查找是 O(1),整体 O(n); - Map 保持插入顺序,结果数组顺序与原数组一致(稳定)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











