Featured image of post 数组去重的几个方法

数组去重的几个方法

一道著名面试题 —— 如何实现数组去重?

假设有数组 array = [1, 5, 2, 3, 4, 2, 3, 1, 3, 4]

你要写一个函数 unique,使得 unique(array) 的值为 [1, 5, 2, 3, 4]

indexOf() 方法

indexOf() 方法返回在类型数组中可以找到给定元素的第一个索引,如果不存在,则返回 -1

那么我们就可以遍历原数组,利用 indexOf() 的返回值判断是否已存在当前元素。代码实现 ⬇️ ⬇️ ⬇️

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const array = [1, 5, 2, 3, 4, 2, 3, 1, 3, 4]

const unique = (array) => {
    let result = []
    
    for (let i = 0; i < array.length; i++) {
        if (result.indexOf(array[i]) === -1) {
            result.push(array[i])
        }
    }
    
    return result
}
  • 思路: 遍历原数组,使用新数组的 indexOf() 判断原数组每一项是否已经存在于新数组,如果不存在则将当前元素加入新数组,如存在则跳过当前元素,最终返回新数组。
  • 优点: 内置方法,简洁易理解,并且兼容旧的 JavaScript 版本
  • 缺点: 无法对数组中的 NaN 去重,无法对相同的数组/对象去重

Set() 方法

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set 中的元素只会出现一次,即 Set 中的元素是唯一的。这是 MDN 对 Set() 的描述。

那么我们就可以利用 Set 对象元素的唯一性进行数组去重。代码实现 ⬇️ ⬇️ ⬇️

1
2
3
4
5
const array = [1, 5, 2, 3, 4, 2, 3, 1, 3, 4]

const unique = (array) => {
    return [...new Set(array)]
}
  • 思路: 创建 Set 对象并传入原数组,由于 Set 中的元素是唯一的,此时 Set 中的元素就已经去过重了,然后将 Set 中的元素组成新数组返回,就是实现了一个数组去重。
  • 优点: 内置方法,简洁方便,支持 NaN 去重
  • 缺点: 无法对相同的数组/对象去重

Map() 方法

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。

代码实现 ⬇️ ⬇️ ⬇️

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const array = [1, 5, 2, 3, 4, 2, 3, 1, 3, 4]

const unique = (array) => {
    let arrMap = new Map()
    let result = []
    
    array.forEach( item => {
        if (!arrMap.has(item)) {
            arrMap.set(item, 1)
            result.push(item)
        }
    })
    
    return result
}
  • 思路: 创建一个 Map 对象,然后对原数组的每一项运行函数 —— 如果 Map 中没有与当前元素相同的键,则将当前元素作为键写入 Map,并将此元素加入新数组中,遍历结束后返回新数组。
  • 优点: 支持 NaN 去重
  • 缺点: 无法对相同的数组/对象去重