JavaScript数组去重方法总结

165 阅读3分钟

JavaScript数组去重

方法总结

  1. **Set:**使用类型转换先将数组转换为set,然后再将set转为数组。
    • 无法对{}[]去重
  2. **排序比较相邻元素:**利用sort(),然后比较相邻元素是否相等
  3. 遍历+ 判断(下面的任意组合)
    • 外层遍历可以使用下面的方法。
      • reduce
      • filter
      • 数组循环 + 临时变量存储结果
      • 数组循环+ 删除原有数组对应元素
    • 判断遍历的当前元素是否已存在
      • 借助API直接判断数组内是否存在某个元素
        • indexOf:对NaN均会返回-1,对于引用类型会比较引用地址
        • includes:对于引用类型会比较引用地址
      • 借助**Map、Object,**然后判断是否已存在
        • Object属性:Object的key是字符串,为其添加属性的时候会调用其toString方法
          • 无法处理引用类型数据。因为会将其转为字符串。
          • 无法处理特殊字符串,("1","NaN","true","null","undefined")
        • Map:对于引用类型会比较引用地址。
      • 遍历数组+自定义比较逻辑
        • 遍历
        • 自定义比较逻辑
          • ===
            • 都为引用类型时,比较引用地址
            • 类型和值都要相同
            • NaN === NaN // false
          • ==
            • 都为引用类型时,比较引用地址
            • 类型不同先进性类型转换,在进行比较
            • NaN === NaN // false
          • 自定义两个元素的比较逻辑

方法实现对比

  • 对于一般的数据类型(不涉及到引用类型的)直接用遍历+includes判断,或者借助于es6的Set。
  • 对于不含有NaN的一般的数据类型,也可以使用 遍历 + indexOf的方法判断。
  • 如果涉及到引用类型的去重,使用遍历+手动写比较函数来处理。

注意点

**

  • 注意去重是否要保持原数组不改动。
  • 注意NaN以及SymBol类型

具体实现

Set

const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];

function unique (arr) {
    return Array.from(new Set(arr))
}

console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

reduce+includes

const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];

function unique(arr) {
    return arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}

console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

reduce+indexOf

const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];

function unique(arr) {
    return arr.reduce((prev, cur) => prev.indexOf(cur) !== -1 ? prev : [...prev, cur], []);
}

console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]

filter+indexOf

const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];

function unique(arr) {
    return arr.filter(function(item, index, arr) {
        //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
        return arr.indexOf(item, 0) === index;
    });
}

console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]