如何在对象数组中使用Set()?为何Set()对对象无效?
为什么Set()没法给对象数组去重?怎么解决?
嘿,这个问题我之前踩过坑!先给你解释下核心原因:
Set 判断元素是否重复的依据是严格相等运算符(===)。对于字符串、数字这类原始类型,值相同就会被判定为重复;但对象不一样——哪怕两个对象的键值对完全一模一样,它们也是内存里的不同引用(你可以理解为存放在不同的“抽屉”里),所以{name: 'harry', id:1} === {name: 'harry', id:1}的结果是false。这就是为什么你用new Set(fullNameList)完全没起到去重效果。
那怎么移除值完全相同的对象重复项呢?给你两种实用的方案:
方案1:用JSON.stringify转字符串去重(适合简单对象)
把每个对象转成JSON字符串,内容完全一致的对象会变成一模一样的字符串,Set就能识别出重复了。之后再把字符串转回对象即可:
let nameList_one = [{ name: 'harry', id: 1 }, { name: 'john', id: 2 }, { 'name': 'trevor', id: 3 }] let nameList_two = [{ name: 'harry', id: 1 }, { name: 'ron', id: 4 }, { name: 'jackson', id: 5 }] let fullNameList = [...nameList_one , ...nameList_two ] // 转字符串去重后再转回对象 const filteredList = [...new Set(fullNameList.map(item => JSON.stringify(item)))] .map(str => JSON.parse(str)); console.log(filteredList); // 输出:[{name: 'harry', id:1}, {name: 'john', id:2}, {name: 'trevor', id:3}, {name: 'ron', id:4}, {name: 'jackson', id:5}]
⚠️ 小提醒:这个方法依赖对象的键顺序,如果两个对象键值对相同但键的排列顺序不一样(比如一个是{name:'a', id:1},另一个是{id:1, name:'a'}),转成字符串后会不一样,就没法去重。如果你的对象键顺序都一致,这个方法完全够用。
方案2:用filter+唯一标识去重(更高效,适合有唯一ID的场景)
看你的示例里每个对象都有唯一的id,直接用id作为判断重复的依据会更高效,也不会有键顺序的问题:
let nameList_one = [{ name: 'harry', id: 1 }, { name: 'john', id: 2 }, { 'name': 'trevor', id: 3 }] let nameList_two = [{ name: 'harry', id: 1 }, { name: 'ron', id: 4 }, { name: 'jackson', id: 5 }] let fullNameList = [...nameList_one , ...nameList_two ] const seenIds = new Set(); const filteredList = fullNameList.filter(item => { if (seenIds.has(item.id)) { return false; } seenIds.add(item.id); return true; }); console.log(filteredList); // 输出和上面一样的去重结果
如果你的对象没有唯一ID,也可以把多个键组合成一个唯一标识(比如${item.name}-${item.age}),用同样的逻辑去重。
内容的提问来源于stack exchange,提问作者Johnson
相关产品推荐
相关产品推荐

