ES6 set和map数据结构对对象数组去重简单实现

自从有了es6的set数据结构,数组的去重可以简单用一行代码实现,比如下面的方式

let arr = [1, 2, 2, 3, 4]
function unique (arr) {
    return [...new Set(arr)]
}
console.log(unique(arr)) // [1, 2, 3, 4]

但是当数组的项不再是简单的数据类型时,比如是对象时,这种方法就会导致错误,比如下面的结果

let arr = [
    { name: 'a', num: 1},
    { name: 'b', num: 1},
    { name: 'c', num: 1},
    { name: 'd', num: 1},
    { name: 'a', num: 1},
    { name: 'a', num: 1},
    { name: 'a', num: 1}
]
function unique (arr) {
    return [...new Set(arr)]
}
console.log(unique(arr)) // 结果为原数组,有兴趣可以复制代码试一下

其中的原因是因为set数据结构认为对象永不相等,即使是两个空对象,在set结构内部也是不等的

基于以上原因,利用map结构封装了一种对对象数组去重的简单方法,具体如下

// ES6对象数组所有属性去重,筛选每个数组项的字符
function unique(arr) {
    const res = new Map()
    return arr.filter( item => !res.has(JSON.stringify(item)) && res.set(JSON.stringify(item), 1))
}
// ES6根据一维对象数组某个属性去重且该属性的值为简单数据类型
function unique(arr, key) {
    const res = new Map()
    return arr.filter((item) => !res.has(item[key] + '') && res.set(item[key] + '', 1))
}

网上有朋友设计了一种更简单的方法,主要是对map数据结构的键理解得不一样,其他没什么区别,代码如下

// ES6对象数组所有属性去重,筛选每个数组项的字符
function unique2(arr) {
    const res = new Map()
    return arr.filter( item => !res.has(item) && res.set(item, 1))
}

实际试了一下,发现没有起到去重的效果,不知道具体原因是什么,我的理解是当用item指代数组中的每一项的对象的时候,item保存的是对对象的指针,即栈中的地址,并不是对象本身,所以每一个item的地址是不一样的,尽管他们都指向同一个堆数据,所以map认为每一个item并不相等,当然就起不到去重的效果。如果有更正确和深入的理解欢迎讨论哈

猜你喜欢

转载自www.cnblogs.com/p-l-u-m/p/10950774.html
今日推荐