JavaScript中用Set实现数组去重是最简洁高效的方式,时间复杂度O(n),一行代码[...new Set(arr)]即可完成;但仅对原始值和引用地址去重,对象需配合Map或自定义逻辑。

JavaScript 中用 Set 实现数组去重,是目前最简洁、高效且原生支持的方式。它自动忽略重复值,时间复杂度接近 O(n),比传统循环或 filter + indexOf 快得多。
直接用 Set 构造器 + 扩展运算符
这是最常用、最直观的一行写法:
```jsconst arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3, 4, 5]
```
-
原理:`new Set(arr)` 把数组转为 Set(自动去重),再用
[...]展开为新数组 - 优点:代码短、可读性强、兼容性好(ES6+)
- 注意:只对原始值(number/string/boolean/symbol/undefined/null)和引用地址去重;对象或数组仍按内存地址判断,不会“深度”去重
处理对象数组的去重(按指定字段)
Set 本身不支持自定义比较逻辑,但可以配合 Map 或生成唯一键来实现:
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 1, name: 'Alice2' } // id 重复
];
// 按 id 去重
const seen = new Set();
const uniqueUsers = users.filter(item => {
if (seen.has(item.id)) return false;
seen.add(item.id);
return true;
// [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
```
- 利用 Set 快速查重(O(1)),配合
filter保持顺序 - 适合按单个字段(如
id、email)去重,逻辑清晰、性能稳定
封装成可复用的去重函数
把逻辑提取出来,增强通用性:
立即学习“Java免费学习笔记(深入)”;
```js// 基础去重(原始值)
const uniq = arr => [...new Set(arr)];
// 按 key 去重对象数组
const uniqBy = (arr, key) => {
const seen = new Set();
return arr.filter(item => {
const val = typeof key === 'function' ? key(item) : item[key];
if (seen.has(val)) return false;
seen.add(val);
return true;
});
// 使用示例
uniq([1, 1, 2, 3]); // [1, 2, 3]
uniqBy(users, 'id'); // 按 id 去重
uniqBy(users, u => u.name.toLowerCase()); // 按名称忽略大小写去重
```
- 支持字符串字段名或回调函数,灵活适配不同场景
- 内部仍基于 Set,保证查重效率
和其它去重方式对比(为什么推荐 Set)
-
vs
filter + indexOf:后者是 O(n²),大数据量明显变慢;Set 是 O(n) -
vs
reduce+ 数组查找:同样存在重复遍历,不如 Set 的哈希查找快 -
vs
Map:功能更重,Set 更轻量,纯去重场景首选 Set -
注意边界:NaN 在 Set 中只保留一个(符合预期),而
Array.prototype.indexOf(NaN)总是返回 -1,容易出错


















