在JavaScript开发过程中,我们经常会遇到需要处理数组重复元素的情况,比如从接口获取的数据存在重复项、用户多次选择相同内容等场景,都需要对数组进行去重操作。不同的去重方法有着不同的实现逻辑和适用场景,下面我们就来逐一介绍常见的数组去重实现方式。

基于Set的去重方法
Set是ES6引入的新数据结构,它的最大特点就是成员的值都是唯一的,没有重复的值,利用这个特性可以非常快速地实现数组去重。
实现代码如下:
// 使用Set实现数组去重
function uniqueBySet(arr) {
// 将数组转换为Set,自动去除重复元素,再转回数组
return [...new Set(arr)];
}
// 测试示例
const testArr1 = [1, 2, 2, 3, 4, 4, 5];
console.log(uniqueBySet(testArr1)); // 输出 [1, 2, 3, 4, 5]
这种方法的优点是代码简洁,执行效率很高,但是需要注意Set是ES6新增的特性,如果项目需要兼容IE等不支持ES6的环境,就不能使用这种方式。
基于indexOf的去重方法
indexOf方法可以返回某个元素在数组中首次出现的位置,利用这个特性可以判断当前元素是否是第一次出现,从而实现去重。
实现代码如下:
// 使用indexOf实现数组去重
function uniqueByIndexOf(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
// 判断当前元素是否在结果数组中存在
if (result.indexOf(arr[i]) === -1) {
result.push(arr[i]);
}
}
return result;
}
// 测试示例
const testArr2 = ['a', 'b', 'b', 'c', 'a'];
console.log(uniqueByIndexOf(testArr2)); // 输出 ['a', 'b', 'c']
这种方法的兼容性比较好,支持ES5及以上的环境,但是indexOf方法在数组较大时性能会有所下降,因为每次判断都需要遍历结果数组。
基于filter的去重方法
filter方法可以过滤数组中的元素,结合indexOf方法可以找到元素第一次出现的位置,从而过滤掉重复的元素。
实现代码如下:
// 使用filter实现数组去重
function uniqueByFilter(arr) {
return arr.filter((item, index) => {
// 判断当前元素的索引是否是第一次出现的索引
return arr.indexOf(item) === index;
});
}
// 测试示例
const testArr3 = [10, 20, 20, 30, 10, 40];
console.log(uniqueByFilter(testArr3)); // 输出 [10, 20, 30, 40]
这种方法的代码也比较简洁,同样存在indexOf性能的问题,而且如果数组中有undefined元素,这种方法也可以正常处理。
基于reduce的去重方法
reduce方法可以对数组中的每个元素执行回调函数,逐步累积结果,利用这个特性也可以实现数组去重。
实现代码如下:
// 使用reduce实现数组去重
function uniqueByReduce(arr) {
return arr.reduce((prev, cur) => {
// 判断累积数组中是否包含当前元素
if (!prev.includes(cur)) {
prev.push(cur);
}
return prev;
}, []);
}
// 测试示例
const testArr4 = [true, false, true, false, true];
console.log(uniqueByReduce(testArr4)); // 输出 [true, false]
这种方法的逻辑比较清晰,includes方法是ES6新增的,如果需要兼容旧环境,可以把includes替换成indexOf判断。
基于双重循环的去重方法
双重循环是比较原始的去重方式,外层循环遍历原数组,内层循环遍历结果数组,判断是否存在重复元素。
实现代码如下:
// 使用双重循环实现数组去重
function uniqueByLoop(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
let isRepeat = false;
for (let j = 0; j < result.length; j++) {
if (arr[i] === result[j]) {
isRepeat = true;
break;
}
}
if (!isRepeat) {
result.push(arr[i]);
}
}
return result;
}
// 测试示例
const testArr5 = [1, '1', 2, 2, '2'];
console.log(uniqueByLoop(testArr5)); // 输出 [1, '1', 2, '2']
这种方法的兼容性最好,几乎所有环境都支持,但是性能相对较差,因为嵌套循环的时间复杂度是O(n²),数组较大时执行速度会明显变慢。
不同去重方法的对比
我们可以通过下面的表格来对比不同去重方法的特点:
| 去重方法 | 兼容性 | 性能 | 代码简洁度 |
|---|---|---|---|
| Set方法 | ES6及以上 | 高 | 高 |
| indexOf方法 | ES5及以上 | 中等 | 中等 |
| filter方法 | ES5及以上 | 中等 | 高 |
| reduce方法 | ES5及以上(includes需ES6) | 中等 | 中等 |
| 双重循环方法 | 全环境支持 | 低 | 低 |
在实际开发中,我们可以根据项目的兼容性要求、数组的大小和代码的简洁性需求来选择合适的去重方法。如果不需要兼容旧环境,优先选择Set方法,代码简洁且性能优秀;如果需要兼容旧环境,数组较小时可以选择indexOf或者filter方法,数组较大时可以考虑优化后的循环方式。
JavaScript数组去重Setfilterreduce修改时间:2026-07-19 22:54:28