总结 js 中数组去重的方法

72 阅读3分钟

数组去重

上周去面试的时候做的笔试题:" 请给出实现数组去重的几种方法 ",面试题一开始准备的不是很充分,刚开始看到这道题的时候也有点懵,很久没做算法题 js 中的一些 API 的使用都给忘记了,依稀记得好像用 Set 可以实现去重,但具体使用已经忘得差不多了......

使用 Set 去重:

Set 是 ES6 中新引入的数据类型,表示 " 一组唯一的值 ",没有重复值,Set 可以存储任意类型的唯一值,适合用来进行数组去重,但是 Set 返回的数据类型是一个 Set 对象,使用 Set 对数组进行去重后,还需要将返回值再转换成数组,具体实现代码如下:

    var arr = [2, 2, 0, 0, 7, 7, 4, 8];
​
    function unique1(arr) {
      let arrObj = new Set(arr);
      return Array.from(arrObj);  // 使用 Array.form() 转换成数组
    }
​
    function unique2(arr) {
      let arrObj = new Set(arr);
      return [...new Set(arr)]; // 使用展开运算符转换成数组
    }
​
   console.log( unique1(arr));  // [2, 0, 7, 4, 8]
   console.log( unique2(arr));  // [2, 0, 7, 4, 8]

使用 indexOf 去重:

indexOf 是一个数组方法,用于查找目标数组指定的元素,并返回其首个索引值,如果目标数组不存在查找的元素,则默认返回 -1 ,indexOf 方法接收两个参数,第一个参数是要查找的元素,第二个参数是指定的起始索引位置。如果省略第二个参数,则从首个元素开始查找;可以使用 indexOf 遍历实现数组去重,具体实现代码如下:

    var arr = [2, 2, 0, 0, 7, 7, 4, 8];
​
    function unique(arr) {
      let result = [];
      for(let i of arr) {
        if(result.indexOf(i) === -1) { 
          result.push(i);
        }
      }
      return result;
    }
​
    console.log(unique(arr)); // [2, 0, 7, 4, 8]

使用 sort 去重:

sort 也是一个数组方法,可以对目标数组进行排序(默认为升序排序),该方法在没有任何拷贝的情况下会改变原数组,返回排序后的数组,使用 sort 进行数组去重的思想与 indexOf 类似:数组中如果存在重复的元素,排序后的相同元素会紧挨在一起,如果本次遍历的元素与下一次遍历的元素值相同,则将该元素进行剔除;具体实现代码如下:

    var arr = [2, 2, 0, 0, 7, 7, 4, 8];
​
    function unique(arr) {
      let result = [];
      let newArr = [...arr];  // 拷贝一份新数组
      newArr.sort();  // 使用 sort 给新数组进行排序
      console.log('改变' + newArr);
      for(let i = 0; i < newArr.length; i++) {
        if(newArr[i] !== newArr[i + 1]) {
            result.push(newArr[i]);
        }
      }
      return result;
    }
​
    console.log(unique(arr));  // [0, 2, 4, 7, 8]

使用 includes 去重:

includes 也是一个数组方法,判断数组中是否存在传入参数中指定的元素,若存在则返回 true,否则返回 false,也是和 indexOf 及 sort 差不多的实现思路,具体实现代码如下:

    var arr = [2, 2, 0, 0, 7, 7, 4, 8];
​
    function unique(arr) {
      let result = [];
      for(let i of arr) {
        if(!result.includes(i)) {
          result.push(i);
        }
      }
      return result;
    }
​
    console.log(unique(arr));  // [2, 0, 7, 4, 8]

使用 Map 去重:

Map 是 ES6 新引入的用于保存键值对的一种数据结构,类似于对象,但对象中的键只能是字符串类型,而 Map 可以将任何类型的值作为键值,且不允许键重复,这一特性可以实现数组去重,去重原理大致为:使用 new Map() 构造一个 map ,遍历目标数组,利用 map.has() 方法判断本次遍历元素是否在 map 当中,如果存在则将该元素排除,依次直到遍历结束,具体实现代码如下:

    var arr = [2, 2, 0, 0, 7, 7, 4, 8];
  
    function unique(arr) {
      let result = [];
      let map = new Map();
      for(let i of arr) {
        if(!map.has(i)) {
          map.set(i, true);  // 将键值设为 true 或其他任意值可以用 Map 的 has 方法来检查元素是否存在
          result.push(i);
        }
      }
      return result;
    }
    
    console.log(unique(arr));  // [2, 0, 7, 4, 8]

在面试中具体能说出3种实现方法应该就差不多了吧。

参考资料:JS数组的 去重【JS面试题】哔哩哔哩bilibili