🧹 JavaScript 数组去重方法总结
我帮你把数组去重的常用方法、原理、优缺点和适用场景整理清楚,你可以根据实际需求选择最合适的方式。
1. Set + 扩展运算符(最简洁高效)
核心思路
利用 Set 数据结构的“元素唯一”特性,将数组转为 Set 自动去重,再转回数组。
代码示例
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5]特点
✅ 代码简洁,一行搞定
✅ 时间复杂度
O(n),性能优秀❌ 无法处理复杂类型(如对象、数组),因为
Set按引用比较❌ 无法保留重复元素的最后一次出现(只能保留第一次)
2. Array.filter() + indexOf
核心思路
用 filter 遍历数组,只保留当前元素第一次出现的项(通过 indexOf 检查索引是否一致)。
代码示例
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每次遍历数组),大数据量性能差❌ 无法处理复杂类型
✅ 保留重复元素的第一次出现
3. Array.reduce() + includes
核心思路
用 reduce 累加结果,每次检查当前元素是否已在结果数组中,不在则加入。
代码示例
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.reduce((acc, cur) => {
if (!acc.includes(cur)) acc.push(cur);
return acc;
}, []);
console.log(uniqueArr); // [1, 2, 3, 4, 5]特点
✅ 逻辑清晰,可灵活扩展(如保留最后一次出现)
❌ 时间复杂度
O(n²)(includes每次遍历数组)❌ 无法处理复杂类型
✅ 可通过调整逻辑保留重复元素的最后一次出现
4. 哈希表(Map/Object)去重
核心思路
用哈希表记录已出现的元素,遍历数组时只保留未记录的元素。
代码示例
const arr = [1, 2, 2, 3, 4, 4, 5];
const map = new Map();
const uniqueArr = [];
for (const item of arr) {
if (!map.has(item)) {
map.set(item, true);
uniqueArr.push(item);
}
}
console.log(uniqueArr); // [1, 2, 3, 4, 5]特点
✅ 时间复杂度
O(n),性能优秀✅ 可以处理复杂类型(需自定义键值,如对象的唯一 ID)
✅ 可灵活控制保留第一次/最后一次出现的元素
❌ 代码比
Set稍长
5. 嵌套循环(不推荐,仅作了解)
核心思路
外层遍历数组,内层检查后续元素是否重复,重复则删除。
代码示例
const arr = [1, 2, 2, 3, 4, 4, 5];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--; // 修正索引,避免跳过元素
}
}
}
console.log(arr); // [1, 2, 3, 4, 5]特点
❌ 时间复杂度
O(n²),性能最差❌ 直接修改原数组,可能引发副作用
❌ 仅适用于教学演示,实际项目中不建议使用
🔍 方法对比表
| 方法 | 时间复杂度 | 空间复杂度 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|---|
Set + 扩展运算符 | O(n) | O(n) | 基本类型去重,追求简洁 | 代码最短,性能高 | 无法处理复杂类型 |
filter + indexOf | O(n²) | O(n) | 小数据量、基本类型 | 代码易读 | 大数据量性能差 |
reduce + includes | O(n²) | O(n) | 需自定义保留逻辑 | 灵活可控 | 性能一般 |
| 哈希表(Map) | O(n) | O(n) | 大数据量、复杂类型 | 性能最优,可处理复杂类型 | 代码稍长 |
| 嵌套循环 | O(n²) | O(1) | 教学演示 | 无额外空间 | 性能最差,修改原数组 |
💡 实战选择建议
日常开发(基本类型):优先用
[...new Set(arr)],简洁高效。大数据量或复杂类型:用
Map哈希表去重,性能最优。需要保留重复元素最后一次出现:用
reduce或Map反向遍历。需要兼容旧环境:用
filter+indexOf(无需 ES6 特性)。
我可以帮你整理一份数组去重测试用例清单,包含基本类型、复杂对象、重复顺序等场景,让你验证每种方法的效果。需要吗?
(注:文档部分内容可能由 AI 生成)