js实现对象数组去重

252 阅读2分钟

前言

相信大家对于数组去重都不陌生,这也是前端面试经常问到的一个问题。在我2021年春招找实习的时候,当时面试携程,一面面试官问我的最后一个问题就是数组去重,我当时回答了三种方法,面试官也比较满意,我也顺利了通过了这次面试。

数组去重

    let arr = [1,2,1,2,1,2,3];
    let newArr = [];

    newArr = [...new Set(arr)];

    for(let i = 0;i < arr.length;i++){
       if(!newArr.includes(arr[i])){
            newArr.push(arr[i]);
       }
    }

    newArr = arr.filter((v,i) => {
       return arr.indexOf(v) === i;
    })
    
    console.log(newArr);  // [1,2,3]

对象数组去重

上面,我们很轻松地实现了数组(元素为数字)去重,可是如果数组中的元素为Array或者Object呢?你可能会想,用set或许可以实现,不幸的是,set对此也无能为力

image.png

原因很简单,mdn中对于set的定义中写到,Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。你可能会想,[1,2]和[1,2]那不是一样的吗?为啥set去不了重呢?其实不然。

image.png

那我们怎么实现对象数组去重呢?请往下看

数组的元素为数组(元素为数字)

既然数组不能,为什么不把数组转化成基本类型的数据呢?比如转化为字符串

function unique(nums) {
    let arr = [];

    arr = nums.map((item) => item.join());   // 利用join转化为字符串

    arr = [...new Set(arr)].map((item) => item.split(','));  // 去重之后利用split转化为数组

    return arr.map((item) => item.map((val) => Number(val))); // 将字符转化为数字
}

let arr = [[1, 1], [1, 1]];

console.log(unique(arr)); // [[1,1]]

数组的元素为对象

function unique(arr) {

  return [...new Set(arr.map(e => JSON.stringify(e)))].map(e => JSON.parse(e));
  
}

let obj1 = {
    name:'kangkang',
    age: 18,
    friends: ['jane'],
    isMale: true
}

let obj2 = {
    name:'kangkang',
    age: 18,
    friends: ['jane'],
    isMale: true
}

let array = [];
array.push(obj1);
array.push(obj2);

console.log(unique(array))  // {name: 'kangkang', age: 18, friends: Array(1), isMale: true}

其中会牵扯到一些值的转化问题!推荐阅读一下 JSON.stringifyJSON.parse