JavaScript对象数组按指定属性去重的核心是用Set或Map记录已出现的属性值再过滤:单属性推荐filter+Set,多属性用Map拼接键,reduce适用于自定义策略或兼容旧环境。

在 JavaScript 中,根据对象的指定属性对数组去重,核心思路是:**提取每个对象中用于判断重复的属性值,用 Set 或 Map 记录已出现过的值,再过滤或构造新数组**。关键在于“指定属性”——可以是单个字段(如 id),也可以是多个字段组合(如 name + age)。
用 filter() + Set(推荐,简洁易懂)
适用于单属性去重,逻辑清晰、性能良好。
- 创建一个空
Set存储已见过的属性值 - 用
filter()遍历数组,对每个对象取指定属性(注意处理undefined或null) - 若该属性值未在
Set中,加入并保留当前项;否则跳过
id 去重
const arr = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 1, name: 'Alice2' }, // 重复 id
{ id: 3, name: 'Charlie' }
];
const uniqueById = arr.filter((item, index, array) => {
const ids = array.map(obj => obj.id);
return ids.indexOf(item.id) === index;
});
// 更高效写法(推荐):
const seen = new Set();
const uniqueById2 = arr.filter(item => {
if (seen.has(item.id)) return false;
seen.add(item.id);
return true;
});
用 Map 实现多属性组合去重
当需根据多个属性(如 name 和 age)联合判断唯一性时,用字符串拼接键更稳妥。
- 将多个属性值转为字符串并拼接(建议用分隔符,如
`${a}|${b}`),避免'12' + '3'和'1' + '23'冲突 - 用
Map存键 → 对象,自动覆盖重复键对应的旧值 - 最后取
Map.values()转为数组
name 和 age 去重
const arr = [
{ name: 'Alice', age: 25, score: 90 },
{ name: 'Bob', age: 30, score: 85 },
{ name: 'Alice', age: 25, score: 95 }, // 完全重复 key
{ name: 'Alice', age: 26, score: 88 }
];
const uniqueByComposite = [...arr.reduce((map, item) => {
const key = `${item.name}|${item.age}`;
map.set(key, item); // 后出现的会覆盖先出现的
return map;
}, new Map()).values()];
用 reduce() 手动累积(兼容性好,逻辑可控)
适合需要自定义保留策略(如保留第一个/最后一个重复项)或兼容老环境(无 Set/Map)。
立即学习“Java免费学习笔记(深入)”;
- 初始化空数组作为累加器
- 遍历原数组,对每个对象计算去重键
- 检查累加器中是否已有相同键的对象,没有则
push
id)
const uniqueByIdReduce = arr.reduce((unique, item) => {
const isExist = unique.some(obj => obj.id === item.id);
return isExist ? unique : [...unique, item];
}, []);
注意事项与避坑点
-
属性不存在时要兜底:如
item.id ?? ''或item.id || null,避免undefined导致误判 -
引用类型慎用:不要直接用对象或数组作为键(
Set或Map里会按引用比较),必须序列化为字符串 -
大小写/空格敏感:如按
name去重,可统一item.name.trim().toLowerCase() -
性能考虑:大数据量时,
filter + Set比reduce + some快得多(后者是 O(n²))


















