测试用例如下:
const arr = [1, 2, 3, 2, 0, 0, 'abc', '', 'bac', '', true, false, true, undefined, null, undefined, null, NaN, NaN];
1. 通过 Set()
简述
因为在Set
对象中,NaN
被认为是相同的值,因此,可以去掉重复的NaN
。并且此方法不会改变原数组。
思路
- 因为
Set
对象中的值是唯一的,所以可以通过Set()
直接去掉数组中重复的值; - 然后使用展开运算符
...
或者Array.from()
将Set
对象转换成数组即可。
代码
// 一、展开运算符,写法超级简单
const removeDuplicate = arr => [...new Set(arr)];
// (12) [1, 2, 3, 0, 'abc', '', 'bac', true, false, undefined, null, NaN]
// 二、Array.from
const removeDuplicate = arr => Array.from(new Set(arr));
// (12) [1, 2, 3, 0, 'abc', '', 'bac', true, false, undefined, null, NaN]
2. 通过循环 + splice()
简述
splice()
方法会改变原数组,若不想改变原数组,可拷贝原数组。由于NaN === NaN
结果为false
,因此该方法无法去掉重复的NaN
。
思路
通过双循环遍历,将元素进行比较,若出现相同的值,则删除该值。
代码
const removeDuplicate = (arr) => {
const 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)
}
}
}
return arr;
}
// (13) [1, 2, 3, 0, 'abc', '', 'bac', true, false, undefined, null, NaN, NaN]
3. 通过 indexOf() 或 includes()
简述
arr.indexOf(item)
可以返回数组arr
中item
元素的索引,若不存在,则返回-1
。这个方法无法去掉重复的NaN
。arr.includes(item)
可以检测数组arr
中是否存在item
元素,若存在,返回true
;若不存在,则返回false
。这个方法可以去掉重复的NaN
。
思路
- 创建一个新数组,用于存储满足条件的值;
- 循环遍历数组,通过
indexOf()
和includes()
检测是否存在相同元素; - 将满足要求的元素
push
到新数组中。
代码
// 一、indexOf()
const removeDuplicate = (arr) => {
const newArr = [];
arr.forEach(element => {
if (newArr.indexOf(element) === -1) {
newArr.push(element);
}
})
return newArr;
}
// (13) [1, 2, 3, 0, 'abc', '', 'bac', true, false, undefined, null, NaN, NaN]
// 二、includes()
const removeDuplicate = (arr) => {
const newArr = [];
arr.forEach(element => {
if (!newArr.includes(element)) {
newArr.push(element);
}
})
return newArr;
}
// (12) [1, 2, 3, 0, 'abc', '', 'bac', true, false, undefined, null, NaN]
4. 通过 sort() + splice()
简述
此方法会改变原数组,可以拷贝原数组之后再排序。且此方法不会去掉重复的NaN
。
思路
- 先将数组进行排序;
- 再循环遍历,两两比较,相邻两个元素若相同则删除其中一个。
代码
const removeDuplicate3 = (arr) => {
arr.sort((a, b) => a - b);
const len = arr.length;
for (let i = 0; i < len; i++) {
if (arr[i] === arr[i + 1]) {
arr.splice(i, 1)
}
}
return arr;
}
// (13) [0, '', false, null, 1, true, 2, 3, 'abc', 'bac', NaN, NaN, undefined]
5. 通过 Map + has()
简述
map
对象可以保存键值对,并且能够记住键的原始插入顺序。这个方法和第三个方法思路差不多,只是改了一下判定条件。这个方法可以去掉重复的NaN
。
思路
- 新建一个
map
对象以及一个新数组newArr
; - 循环遍历数组,并通过
has()
方法来判定是否存在指定键; - 若满足条件就将这个元素
push
到newArr
中。
代码
const removeDuplicate4 = (arr) => {
const map = new Map();
const newArr = [];
arr.forEach(element => {
if (!map.has(element)) {
map.set(element, '');
newArr.push(element);
}
})
return newArr;
}
// (12) [1, 2, 3, 0, 'abc', '', 'bac', true, false, undefined, null, NaN]
结尾
数组去重的方法多种多样,比如还可以使用Array.reduce()
。总体思路都大致一样,主要就是循环+比较,只不过不同的api给我们集成了这些功能,使得方法变得多样性。