js实现数组去重的几种方式
例数组如下
const arr = [1, 2, 2, 'abc', 'abc', true, true, false, false, undefined, undefined, NaN, NaN]
一 、使用set集合和…扩展运算符或Array.from
- Set是ES6中引入的一种数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。
- 将数组转换为Set可以去重,然后再将Set转换回数组即可得到去重后的结果。
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 'abc', true, false, undefined, NaN]
//使用Array.from
const result = Array.from(new Set(arr))
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
需要注意的点是:以上去方式对NaN和undefined类型去重也是有效的,是因为NaN和undefined都可以被存储在Set中,
NaN之间被视为相同的值(尽管在js中:NaN !== NaN)。
二、使用filter和indexOf
- filter方法用于筛选数组中满足条件的元素,返回一个新的数组。
- indexOf方法用于获取元素在数组中的索引,如果元素不存在,则返回-1。
- 通过遍历数组,在filter回调函数中使用indexOf判断元素第一次出现的位置,如果与当前索引相等,则表示是第一次出现的元素,保留下来。
const uniqueArr = arr.filter((value, index, self) => {
return self.indexOf(value) === index;
});
console.log(uniqueArr); // [1, 2, 'abc', true, false, undefined]
需要注意的点是:由于NaN不等于本身,所以过滤出来的数组将不保留NaN
三、使用reduce和includes
- reduce方法用于对数组中的元素进行累积操作,返回一个最终的累积结果。
- includes方法用于判断数组中是否包含某个元素,返回布尔值。
- 利用reduce方法遍历数组,使用includes方法判断当前元素是否已经存在于累积结果中,若不存在则添加到累积结果中。
const uniqueArr = arr.reduce((result, current) => {
if (!result.includes(current)) {
result.push(current);
}
return result;
}, []);
console.log(uniqueArr); // [1, 2, 'abc', true, false, undefined, NaN]
这种方法也可以正确去重NaN
四、使用Map
- Map是ES6中引入的一种数据结构,它类似于对象,但键可以是任意数据类型,而不仅限于字符串,并且它是一种有序的键值对集合,其中键是唯一的
- 通过map方法将数组中的每个元素映射为一个包含键值对的数组,其中键和值都是元素本身
- 而后将map得到的数组集合放入Map对象中,重复的键会被自动去重,只保留最后一个键值对
- 过values方法获取Map中的所有值,得到Map中的所有值集合
- 最后传递给Array.from方法,将Map集合的值提取出来,得到一个新的去重数组
const uniqueArr = Array.from(new Map(arr.map((value) => [value, value])).values());
console.log(uniqueArr); // [1, 2, 'abc', true, false, undefined, NaN]
五、使用for循环与indexOf
- 使用for循环遍历数组,通过indexOf方法判断当前元素是否已经存在于新数组中。
- 如果不存在,则将其添加到新数组中。
- 这种方法不是很高效,因为每次都需要通过indexOf方法进行线性查找,时间复杂度较高。
const uniqueArr = [];
for (let i = 0; i < arr.length; i++) {
if (uniqueArr.indexOf(arr[i]) === -1) {
uniqueArr.push(arr[i]);
}
}
console.log(uniqueArr); // [1, 2, 'abc', true, false, undefined, NaN, NaN]
综上便是几种常用的数组去重方法,其中第1、3、4种方法还可以正确去重NaN,第二种方法将不保留NaN,第五种方法则是无法完成NaN的去重