如何基于多个属性对对象数组去重?ES6 Set无法满足需求
嘿,这个场景我太熟悉了!直接用new Set(arr)肯定行不通,因为对象是引用类型——哪怕两个对象的name和surname完全一样,它们在内存里也是不同的引用,Set根本认不出来。
不过要基于两个属性做高效去重,有两种非常好用的O(n)时间复杂度方法(比嵌套循环那种O(n²)的快多了,大数组里差距特别明显),给你演示一下:
方法1:用Set跟踪唯一组合键
核心思路是把每个对象的name和surname拼接成一个唯一的字符串键,用Set记录已经出现过的键,过滤数组时只保留第一次出现的对象:
let arr = [ { name: "George", surname: "Hendricks" }, { name: "George", surname: "Marques" }, { name: "George", surname: "Hendricks" } ]; const seenKeys = new Set(); const uniqueArr = arr.filter(item => { // 生成唯一键:可以用分隔符拼接,或者更稳妥的JSON.stringify const uniqueKey = `${item.name}|${item.surname}`; // 也可以用 JSON.stringify([item.name, item.surname]),避免属性值含分隔符的冲突 if (seenKeys.has(uniqueKey)) { return false; } seenKeys.add(uniqueKey); return true; }); console.log(uniqueArr); // 输出:[{name: "George", surname: "Hendricks"}, {name: "George", surname: "Marques"}]
方法2:用Map存储已出现的对象
如果想更直观地保存去重后的对象本身,可以用Map——键还是组合字符串,值是对应的对象,最后把Map的values转成数组就行:
const uniqueMap = new Map(); arr.forEach(item => { const uniqueKey = `${item.name}|${item.surname}`; // 只存第一次出现的对象 if (!uniqueMap.has(uniqueKey)) { uniqueMap.set(uniqueKey, item); } }); const uniqueArr = Array.from(uniqueMap.values());
小提醒
如果你的对象属性可能出现undefined、null这类值,最好给个默认值(比如item.name ?? ''),避免生成undefined-Marques这种奇怪的键,导致误判。
内容的提问来源于stack exchange,提问作者adot
相关产品推荐
相关产品推荐

