七种JS实现数组去重的方式

作者:木棉时间:2026-10-24 20:56:41浏览:433

本文详细解析七种JavaScript数组去重方案,涵盖Set、双层循环splice、indexOf、includes、filter结合indexOf、Map及对象属性法。重点对比各方法对NaN和undefined的处理差异,揭示includes与Map底层对NaN判等的特殊机制,帮助开发者根据数据类型选择最优去重策略。

示例:对包含多种数据类型的数组进行去重处理。


const arr = [1, 2, 2, 'abc', 'abc', true, true, false, false, undefined, undefined, NaN, NaN]


1. 利用Set()与Array.from()

  • Set对象是一个值集合,支持按插入顺序迭代其元素。Set中的每个值仅出现一次,确保元素唯一性。
  • Array.from()方法用于将类数组对象或可迭代对象转换为新的浅拷贝数组实例。

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


注意:上述方法对NaN和undefined类型的去重同样有效。这是因为Set允许存储NaN和undefined,且Set内部将NaN视为相同的值(尽管在JavaScript中NaN !== NaN为真)。

2. 利用双层循环结合splice方法

通过双层循环逐一比较数组元素,并利用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 ]

3. 利用数组的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 ]

4. 利用数组的includes方法

此方法的逻辑与indexOf方法去重类似,但使用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能检测数组中包含NaN,这与其底层实现有关。如下代码所示,判断是否包含某元素时会调用sameValueZero方法进行比较,若为NaN,则使用isNaN()进行转换处理。

简单测试includes()对NaN的判断结果:


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


5. 利用数组的filter()结合indexOf()

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


6. 利用Map()

Map对象是JavaScript提供的一种数据结构,结构为键值对形式。将数组元素作为Map的键存入,前端培训然后结合has()和set()方法判断键是否重复。

Map对象用于保存键值对,并能记住键的原始插入顺序。任何值(对象或原始值)均可作为键或值。


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相等,其余所有值根据===运算符的结果判断是否相等。

7. 利用对象

其实现思想与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实现数组去重方式的介绍结束。更多相关JS数组去重内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

作者最新文章