javascript中用map实现对象数组去重的核心是利用其键的唯一性,通过拼接指定属性(如item.id + '_' + item.email)生成唯一键,遍历中检查键是否存在,不存在则存入map并保留对象,从而高效完成去重。

JavaScript 中用 Map 实现对象数组去重,核心是利用其键的唯一性与引用/序列化控制能力,比遍历 + findIndex 或 filter + some 快得多,尤其在大数据量时优势明显。
用对象属性组合生成唯一键
多数场景下,我们按一个或多个字段判断“重复”,比如 id、name 和 email。这时可以把这些字段拼成字符串作为 Map 的键:
- 先创建空
Map - 遍历原数组,对每个对象提取关键属性,拼成唯一字符串(如
item.id + '_' + item.email) - 若该键未存在,存入
Map并推入结果数组;否则跳过
示例:
const arr = [
{ id: 1, name: 'Alice', email: 'a@b.com' },
{ id: 2, name: 'Bob', email: 'b@c.com' },
{ id: 1, name: 'Alice', email: 'a@b.com' }, // 重复
];
const seen = new Map();
const unique = [];
for (const item of arr) {
const key = `${item.id}_${item.email}`;
if (!seen.has(key)) {
seen.set(key, true);
unique.push(item);
}
}
// unique = [{ id: 1, ... }, { id: 2, ... }]
处理嵌套结构或动态字段时用 JSON.stringify(谨慎)
如果去重依据是整个对象结构(或部分深层字段),且字段顺序固定、不含函数/undefined/Symbol/Date 等不可序列化值,可用 JSON.stringify 生成键:
- 仅适用于纯数据对象(POJO),不推荐用于含方法、循环引用、时间对象的数组
- 确保字段顺序一致(建议提前
Object.keys().sort()再序列化,或使用structuredClone+ 自定义比较逻辑替代) - 性能略低于字符串拼接,但写法更通用
简单示例(仅限安全场景):
const uniqueByShape = [];
const map = new Map();
for (const item of arr) {
const key = JSON.stringify(item); // ⚠️ 注意限制条件
if (!map.has(key)) {
map.set(key, true);
uniqueByShape.push(item);
}
}
用 Map 存对象引用 + 自定义比较逻辑(高阶用法)
当需要深度比较(如忽略某些字段、支持容差、或处理 Date/RegExp)时,Map 本身不支持自定义键比较,但可以反向操作:
- 把已接受的对象存进
Map的值里,键仍用简单标识(如递增 ID) - 每次插入前,手动用
Array.from(map.values())遍历做深比较(适合中小数组) - 更优解是改用
Set配合自定义序列化函数,或引入lodash.isEqual等工具
不推荐纯靠 Map 做复杂深比较——它设计初衷不是替代比较器,而是提供 O(1) 查找。
对比其他方法:为什么 Map 更快?
Map 底层通常基于哈希表实现,has/set 平均时间复杂度为 O(1);而 Array.includes、findIndex 或 some 每次都要线性扫描,整体达 O(n²):
- 1000 条数据:
Map约 1000 次哈希操作;嵌套循环约 50 万次比较 - 1 万条时,差距扩大到百倍以上
- 内存占用略高(存了键和布尔值),但换来了显著速度提升
真正影响性能的不是 Map 本身,而是你选的键是否稳定、可预测、无歧义。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











