JavaScript 数组去重

84 阅读2分钟
const arr = [1, 2, 2, 'abc', 'abc', true, true, false, false, undefined, undefined, NaN, NaN]

Set()+Array.from()

  • Set元素是唯一的

  • Array.from()类似数组可迭代对象,创建一个新的浅拷贝的数组实例

const result = Array.from(new Set(arr))
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
  • NaNundefined类型去重也是有效的

    • NaNundefined都可以被存储在Set中, NaN之间被视为相同的值

    • NaN !== NaN

两层循环+数组的splice方法

  • 对NaN是无法进行去重的

    • 进行比较时NaN !== NaN
function removeDuplicate(arr) {
  let len = arr.length
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1)
        len-- // 减少循环次数提高性能
        j-- // 保证j的值自加后不变
      }
    }
  }
  return arr
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]

利用数组的indexOf方法

  • 无法对NaN去重

  • indexOf() :返回调用它的String对象中第一次出现的指定值的索引

    • 从 fromIndex 处进行搜索,如果未找到该值,则返回 -1
function removeDuplicate(arr) {
  const newArr = []
  arr.forEach(item => {
    if (newArr.indexOf(item) === -1) {
      newArr.push(item)
    }
  })
  return newArr // 返回一个新数组
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]

利用数组的includes方法

  • includes():判断一个数组是否包含一个指定的值

    • 返回 true/false
function removeDuplicate(arr) {
  const newArr = []
  arr.forEach(item => {
    if (!newArr.includes(item)) {
      newArr.push(item)
    }
  })
  return newArr
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
  • includes能够检测到数组中包含NaNincludes`底层的实现

    image.png

    • includes()NaN的判断

      const testArr = [1, 'a', NaN]
      console.log(testArr.includes(NaN)) // true
      

利用数组的filter()+indexOf()

  • filter() 方法:会创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
function removeDuplicate(arr) {
  return arr.filter((item, index) => {
    return arr.indexOf(item) === index
  })
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined ]
  • 结果中不包含NaN,是因为indexOf()无法对NaN进行判断

    • arr.indexOf(item) === index返回结果为false

      const testArr = [1, 'a', NaN]
      console.log(testArr.indexOf(NaN)) // -1
      

利用Map()

  • Map 对象:用于保存键值对,并且能够记住键的原始插入顺序

    • has()set()方法判断键是否重复
    function removeDuplicate(arr) {
      const map = new Map()
      const newArr = []
    
      arr.forEach(item => {
        if (!map.has(item)) { // has()用于判断map是否包为item的属性值
          map.set(item, true) // 使用set()将item设置到map中,并设置其属性值为true
          newArr.push(item)
        }
      })
    
      return newArr
    }
    
    const result = removeDuplicate(arr)
    console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
    
  • Map()也可对NaN

    • Map进行判断时认为NaN是与NaN相等的

利用对象

其实现思想和Map()是差不多的,主要是利用了对象的属性名不可重复这一特性。

function removeDuplicate(arr) {
  const newArr = []
  const obj = {}

  arr.forEach(item => {
    if (!obj[item]) {
      newArr.push(item)
      obj[item] = true
    }
  })

  return newArr
}

const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]

参考:js实现数组去重的方式(7种)_MomentYY的博客-CSDN博客