❝不管在实际工作还是面试场景中数组去重都非常重要,总结一下
❞
最简单场景
const arr = [1, 1, 2, 2, 3, 3];
- 双重循环
const uniqueArr = (arr) => {
const res = [];
for (var i = 0; i < arr.length; i += 1) {
for (var j = 0; j < res.length; j += 1) {
if (arr[i] === res[j]) break;
}
if (j === res.length) {
res.push(arr[i])
}
}
return res
}
console.log(uniqueArr(arr)); // [1,2,3]
- indexOf配合单层循环
const uniqueArr = (arr) => {
const res = [];
for (let i = 0; i < arr.length; i += 1) {
if (res.indexOf(arr[i]) === -1) res.push(arr[i])
}
return res
}
- filter 也可以
const uniqueArr = (arr) => {
return arr.filter((item, index, array) => {
if (array.indexOf(item) === index) return true
})
}
有特殊值的场景
const arr = [1, 1, NaN, NaN]
❝由于
❞NaN===NaN返回 false,因此使用 indexOf 判断的方式无法去重这种特殊值,此时可以考虑使用较新版本的 API 或者数据结构。
- includes 配合遍历
const uniqueArr = (arr) => {
const res = [];
for (let i = 0; i < arr.length; i += 1) {
if (!res.includes(arr[i])) res.push(arr[i])
}
return res;
}
console.log(uniqueArr(arr)); // [1, NaN]
- 使用 Set
const res = [...new Set(arr)];
有对象类型
const arr = [1,1,'1',2,2,'2',NaN,NaN,{},{}]
❝当数组元素含有如
❞{}相同的多个元素时,使用上述方法无法去重,可使用对象键值对的方式
- 对象键值对
const uniqueArr = (arr) => {
const obj = {};
return arr.filter(item => {
if (!obj.hasOwnProperty(typeof item + item)) {
obj[typeof item + item] = true;
return true
}
})
}
console.log(uniqueArr(arr)); // [ 1, "1", 2, "2", NaN, {} ]
❝将对象的键名构造成
❞typeof item + item而非简单的item是为了处理像1 和 '1'的情况
- obj 可以用来去重,Map 当然也行
const uniqueArr = (arr) => {
const map = new Map();
return arr.filter(item => {
if (!map.has(typeof item + item)) {
map.set(typeof item + item, true);
return true;
}
})
}
❝此外还可采用先排序再去重等方式进行优化
❞
本文使用 mdnice 排版