在JavaScript开发中,数组去重是一个常见需求。本文将介绍多种实现数组去重的方法,帮助开发者根据不同的场景选择最适合的方案。
1. 使用Set数据结构(ES6)
ES6引入的Set数据结构天然具有去重特性,这是最简单高效的去重方法:
javascript
const uniqueArray = [...new Set(array)];
// 或者
const uniqueArray = Array.from(new Set(array));
优点:代码简洁,性能优秀
缺点:无法处理特殊对象(如对象数组的去重)
2. 使用filter和indexOf
javascript
const uniqueArray = array.filter((item, index) => {
return array.indexOf(item) === index;
});
优点:兼容性好,支持ES5环境
缺点:对于大型数组性能较差,时间复杂度O(n²)
3. 使用reduce方法
javascript
const uniqueArray = array.reduce((acc, current) => {
if (!acc.includes(current)) {
acc.push(current);
}
return acc;
}, []);
优点:函数式编程风格,可读性好
缺点:性能中等,对于大型数组不如Set高效
4. 使用对象键值对
javascript
const obj = {};
const uniqueArray = [];
for (let item of array) {
if (!obj[item]) {
uniqueArray.push(item);
obj[item] = true;
}
}
优点:性能较好,时间复杂度O(n)
缺点:会将所有元素转为字符串,不适合对象数组
5. 双层循环(传统方法)
javascript
const uniqueArray = [];
for (let i = 0; i < array.length; i++) {
let isDuplicate = false;
for (let j = 0; j < uniqueArray.length; j++) {
if (array[i] === uniqueArray[j]) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
uniqueArray.push(array[i]);
}
}
优点:兼容性最好,无需任何ES6特性
缺点:性能最差,时间复杂度O(n²)
6. 针对对象数组的去重方案
对于对象数组,上述方法可能无法直接使用,需要特殊处理:
javascript
const uniqueObjectArray = array.reduce((acc, current) => {
const isDuplicate = acc.some(item =>
JSON.stringify(item) === JSON.stringify(current)
);
if (!isDuplicate) {
acc.push(current);
}
return acc;
}, []);
注意:这种方法性能较差,且JSON.stringify可能无法处理循环引用
性能比较
在大多数现代JavaScript引擎中,性能从高到低排序大致为:
- Set方法
- 对象键值对方法
- reduce方法
- filter+indexOf方法
- 双层循环方法
总结
选择哪种去重方法取决于:
- 运行环境(是否需要支持旧浏览器)
- 数组大小(性能考虑)
- 数组元素类型(基本类型还是对象)
对于现代浏览器环境,优先推荐使用Set方法;如果需要兼容旧环境,可以考虑reduce或filter方法;对于对象数组,则需要根据具体情况定制去重逻辑。