✅ 一、最简单(推荐首选)
👉 使用 Set(ES6)
const arr = [1, 2, 2, 3, 4, 4];
const result = [...new Set(arr)];
console.log(result); // [1, 2, 3, 4]
✔ 优点:
-
写法最简洁
-
性能好(接近 O(n))
✔ 缺点:
- 无法处理对象去重(引用不同)
✅ 二、使用 filter
const arr = [1, 2, 2, 3, 4, 4];
const result = arr.filter((item, index) => {
return arr.indexOf(item) === index;
});
console.log(result);
✔ 原理:
- 只保留第一次出现的位置
❗ 缺点:
- 性能较差(O(n²))
✅ 三、使用 reduce
const arr = [1, 2, 2, 3, 4, 4];
const result = arr.reduce((acc, cur) => {
if (!acc.includes(cur)) {
acc.push(cur);
}
return acc;
}, []);
console.log(result);
✔ 适合理解函数式编程
✅ 四、使用 Map(推荐处理复杂数据)
const arr = [1, 2, 2, 3, 4, 4];
const map = new Map();
const result = [];
arr.forEach(item => {
if (!map.has(item)) {
map.set(item, true);
result.push(item);
}
});
console.log(result);
✔ 优点:
-
性能好
-
可扩展(对象去重)
🚀 五、对象数组去重(面试重点🔥)
👉 按某个字段去重
const arr = [
{ id: 1, name: 'a' },
{ id: 1, name: 'b' },
{ id: 2, name: 'c' }
];
const map = new Map();
const result = arr.filter(item => {
if (!map.has(item.id)) {
map.set(item.id, true);
return true;
}
return false;
});
console.log(result);
🧠 六、终极通用写法(封装函数)
function unique(arr, key) {
const map = new Map();
return arr.filter(item => {
const value = key ? item[key] : item;
if (!map.has(value)) {
map.set(value, true);
return true;
}
return false;
});
}
使用👇
unique([1, 2, 2, 3]);
unique([{id:1},{id:1}], 'id');
⚠️ 七、面试加分点(必须知道)
1️⃣ Set 去重不了对象
[{a:1}, {a:1}] // ❌ 还是两个
原因:
👉 引用地址不同
2️⃣ 性能排序(面试常问)
| 方法 | 时间复杂度 |
|---|---|
| Set | ⭐ O(n) |
| Map | ⭐ O(n) |
| filter | ❌ O(n²) |
| includes | ❌ O(n²) |
3️⃣ 特殊值问题
NaN === NaN // false
👉 但:
new Set([NaN, NaN]) // ✅ 只保留一个
✍️ 总结一句话
👉 简单数据用 Set,复杂数据用 Map,面试优先讲这两个