JavaScript数组去重的六种方式
本文介绍了JavaScript中数组去重的六种常用方法。包括使用双重循环、对象或Map存储、indexOf与lastIndexOf配合、ES6的展开运算符结合Set、filter结合indexOf,以及利用JSON序列化与反序列化的技巧。每种方法都分析了其原理、优缺点及适用场景,帮助开发者根据实际需求选择最优方案。
一、最朴素的方法去重:双重for循环
提到数组去重,最直接的想法是使用双重for循环,通过遍历两层来比较元素。需要注意的是,在使用数组的splice方法删除重复项后,必须将第二层循环的索引减1,否则会导致数组塌陷问题,即跳过某些元素的检查。
function unique(arr) {
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--; // 注意:由于删除了元素,需要将 j 减一,以避免漏掉第j项的检查
}
}
}
return arr;
}
const arr = [1,1,2,2,3,4,4,5,5,6];
console.log(unique(arr));
// 输出:[ 1, 2, 3, 4, 5, 6 ]
二、最省时间的去重:obj/Map存储 + for循环
由于对象Object的key具有唯一性,我们可以利用这一特性进行去重。核心思路是使用对象或者Map将遍历过的项作为key存储到对象或Map中。如果遇到已存在的key,则说明出现了重复项,直接忽略该项即可。
function unique(arr) {
const obj = {}; // 这里可以换成Map
const newArr = [];
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
if (!obj[item]) {
obj[item] = 1;
newArr.push(item);
}
}
return newArr;
}
这是典型的空间换时间策略,可将时间复杂度从O(n²)降低至O(n)。通过利用对象存储,实现空间换时间的效果,从而节约执行时间。
三、最好理解的去重:indexOf + lastIndexOf
JavaScript提供了indexOf和lastIndexOf两个方法,分别用于从数组的第一项和最后一项开始查找目标项。若找到,则返回对应的索引值。如果某一项通过indexOf和lastIndexOf查找到的索引相同,则证明该项不存在重复;反之,则存在重复项。
这种去重方式易于理解。但需注意,这里同样使用了splice,因此需要处理防止数组塌陷的问题。
function unique(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])) {
arr.splice(i, 1);
i--; // 注意:由于删除了元素,需要将 i 减一,以避免漏掉第i项的检查
}
}
return arr;
}
四、最简单的去重:展开运算符 + Set
利用ES6的新特性,即展开运算符结合Set,应该是最简单的去重方式,且编写的字符数最少。
function unique(arr) {
return [...new Set(arr)];
}
五、最有趣的去重:filter + indexOf去重
利用filter结合indeOf也可以实现去重,且只需一行代码,非常有趣。
核心思路是:在使用filter遍历时,通过indexOf查找当前遍历项的索引。如果查找到的索引与此时filter遍历的index一致,说明在当前项之前未出现与当前项相同的重复项,因此该项需要保留;反之,则需要剔除。而filter自带过滤功能,返回true时保留该项,返回false时剔除该项。
function unique(arr) {
return arr.filter((item, index) => arr.indexOf(item) === index);
}
const arr = [1,1,2,2,3,4,4,5,5,6];
console.log(unique(arr));
// 输出:[ 1, 2, 3, 4, 5, 6 ]
六、最骚的去重:JSON.stringify + Set + JSON.parse
或许令人意外,利用JSON.stringify、Set和JSON.parse也能实现去重,这应是最具创意的去重方式,且天然支持对存放数组的对象进行去重。
去重的核心思路如下:
- 利用
JSON.stringify将数组每一项存储的对象或普通值进行序列化,将原数组转换为字符串数组; - 利用
Set对字符串数组进行去重; - 利用
JSON.parse对数组每一项进行反序列化。
需要注意的是,如果两个对象存储的key和value都相同,则它们序列化的结果也相同,因此这种方式天然支持对对象进行去重。
function unique(arr) {
return [...new Set(arr.map(t => JSON.stringify(t)))].map(s => JSON.parse(s));
}
const arr = [1,1,2,2,3,4,4,5,5,6];
const arr1 = [{ a:1 }, { a:1 }, { a:2 }, { a:2 }, { a:3 }, { a:3 }, { a:4 }, { a:4 }, { a:5 }, { a:5 } ]
console.log(unique(arr));
console.log(unique(arr1));
/**
* 打印结果:
* [ 1, 2, 3, 4, 5, 6 ]
* [ { a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }, { a: 5 } ]
*/
以上介绍了6种JavaScript去重方式。我平常最常用的就是第四种,即展开运算符结合Set去重。不知道大家在平时实际开发中更喜欢哪一种去重方式?或者还有没有其它更好的去重方式?
到此这篇关于JavaScript数组去重的六种方式的文章就介绍到这了,更多相关JavaScript数组去重内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58
