数组去重

数组去重

去重

在 JavaScript 中,数组去重有多种实现方式,每种方法都有其特点和适用场景。以下是常见的数组去重方法:

1. 使用 Set

Set 是一种数据结构,它会自动去除重复的值。这是最简单且效率较高的去重方法。

示例代码

1
2
3
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5]

优点

  • 简洁易读。
  • 性能较好,时间复杂度为 O(n)。

缺点

  • 不兼容旧版本浏览器(IE 等)。

2. 使用 filter 和 indexOf

利用 indexOf 的特性,只有第一次出现的元素的索引才会与当前索引相等。

示例代码

1
2
3
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

优点

  • 兼容性好,所有现代浏览器都支持。
  • 逻辑清晰。

缺点

  • 时间复杂度较高,为 O(n²),因为 indexOf 本身是 O(n) 的操作。

3. 使用 Map

Map 是一种键值对集合,可以利用它的键唯一性来去重。

示例代码

1
2
3
4
const arr = [1, 2, 2, 3, 4, 4, 5];
const map = new Map();
const uniqueArr = arr.filter(item => !map.has(item) && map.set(item, true));
console.log(uniqueArr); // [1, 2, 3, 4, 5]

优点

  • 性能较好,时间复杂度为 O(n)。
  • 兼容性好。

缺点

  • 代码稍显复杂。

4. 使用对象(哈希表)

利用对象的键唯一性来去重。

示例代码

1
2
3
4
5
6
const arr = [1, 2, 2, 3, 4, 4, 5];
const hash = {};
const uniqueArr = arr.filter(item => {
return hash.hasOwnProperty(item) ? false : (hash[item] = true);
});
console.log(uniqueArr); // [1, 2, 3, 4, 5]

优点

  • 性能较好,时间复杂度为 O(n)。
  • 兼容性好。

缺点

  • 代码稍显复杂。

5. 手动去重(循环 + 判断)

通过嵌套循环逐个检查元素是否重复。

示例代码

1
2
3
4
5
6
7
8
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [];
for (let i = 0; i < arr.length; i++) {
if (!uniqueArr.includes(arr[i])) {
uniqueArr.push(arr[i]);
}
}
console.log(uniqueArr); // [1, 2, 3, 4, 5]

优点

  • 不依赖现代 JavaScript 的新特性,兼容性极好。

缺点

  • 时间复杂度较高,为 O(n²)。
  • 代码较冗长。

6. 使用 reduce 和 Set

结合 reduceSet 实现去重。

示例代码

1
2
3
4
5
6
7
8
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.reduce((acc, item) => {
if (!acc.includes(item)) {
acc.push(item);
}
return acc;
}, []);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

优点

  • 使用了函数式编程的思想,代码更简洁。
  • 兼容性好。

缺点

  • 时间复杂度较高,为 O(n²)。

7. 使用 Object.keys

利用对象的键唯一性,通过 Object.keys 去重。

示例代码

1
2
3
4
5
6
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = Object.keys(arr.reduce((acc, item) => {
acc[item] = true;
return acc;
}, {}));
console.log(uniqueArr); // ["1", "2", "3", "4", "5"]

优点

  • 利用对象的键唯一性,代码简洁。
  • 性能较好,时间复杂度为 O(n)。

缺点

  • 返回的结果是字符串数组,需要额外处理。

8. 使用 ES6 的 Array.from

结合 SetArray.from 去重。

示例代码

1
2
3
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = Array.from(new Set(arr));
console.log(uniqueArr); // [1, 2, 3, 4, 5]

优点

  • 代码简洁。
  • 性能较好,时间复杂度为 O(n)。

缺点

  • 不兼容旧版本浏览器。

总结

  • 推荐使用方法:如果兼容性不是问题,推荐使用 SetMap,因为它们的性能较好且代码简洁。
  • 兼容性优先:如果需要兼容旧版本浏览器,可以使用 filterindexOf 或手动去重方法。
  • 函数式编程:如果喜欢函数式编程,可以使用 reduceSet 的组合。
    根据你的具体需求选择合适的方法即可!