本文详细解析JavaScript中数组去重的五种常用方法,包括利用对象属性、Set、Map、filter结合indexOf以及reduce结合includes。通过代码示例对比各方法的实现逻辑,并针对10000条以上数据量进行性能测试,指出Set方法在效率与代码简洁性上的优势,同时提供其他补充方案供不同场景选择。
首先准备一个包含重复元素的原始数组。
const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}];
1. 利用对象属性与indexOf
该方法的核心思路是利用对象属性的唯一性来过滤重复项。
具体操作是遍历原数组,检查新数组中是否已存在当前元素,若不存在则将其添加至新数组。
最终将处理后的新数组返回。
此方式的优势在于执行效率较高,但缺点是需要占用额外的内存空间。
var newArr = [];
arr.forEach((key,index)=>{
if(newArr.indexOf(key) === -1){
newArr.push(key)
}
})
console.log(newArr);// [1, '1', 17, true, false, 'true', 'a', {}, {}]2. 使用new Set
Set是ES6引入的一种数据结构,它允许存储任何类型的唯一值。将待去重的数组传入Set构造函数,Set会自动剔除重复元素。
随后通过展开运算符或Array.from将Set转换回数组。这种方法代码简洁且运行效率高,主要局限在于对低版本浏览器的兼容性支持不足。
const newArr = [...new Set(arr)];
console.log(newArr);// [1, '1', 17, true, false, 'true', 'a', {}, {}]3. 使用new Map
利用Map对象键名唯一的特性,通过遍历数组将元素作为键和值存入Map。由于同名键会被覆盖,最终遍历Map提取值即可得到去重后的数组。
const m = new Map();
for (let i = 0; i < arr.length; i++) {
m.set(arr[i], arr[i]);
}
const newArr = []
m.forEach(function (value, key) {
newArr .push(value)
})
console.log(newArr );//[1, '1', 17, true, false, 'true', 'a', {}, {}]4. filter结合indexOf
filter方法会对数组中的每个元素执行回调函数,根据返回值决定保留该元素。此处通过判断当前元素首次出现的索引是否等于当前索引来筛选唯一值。
这种写法的优势在于可以在过滤过程中灵活插入对元素的额外操作,扩展性较强。
const newArr= arr.filter(function(item,index,self){
return self.indexOf(item) === index;
})
console.log(newArr);// [1, '1', 17, true, false, 'true', 'a', {}, {}]5. reduce结合includes
reduce方法用于对数组元素执行累加器函数,将结果累积为单个值。
实现思路是传入一个空数组作为累加器,遍历原数组时检查累加器中是否已包含当前元素,若不包含则push进累加器,最终返回该数组。
这种方法的缺点是比较耗时,且同样需要额外的内存空间来存储中间结果。
const newArray = arr.reduce((newArr, element) => {
if (!newArr.includes(element)) {
newArr.push(element);
}
return newArr;
}, []);注意事项:
当数据量较小(例如10000条以内)时,上述五种方法的性能差异并不显著。
然而,当数据量超过10000条时,前两种方法(对象属性法和Set法)的时间消耗最少,后三种方法的时间消耗依次增加。
关于空间占用,第一种方法较多,但随着现代项目普遍不再兼容低版本浏览器,这一因素权重降低。
综合推荐优先使用Set方法进行去重。
补充方案
除了上述五种主流方法外,还有多种其他方式可以实现数组去重,以下列举部分常见实现。
例如利用双层for循环配合splice方法删除重复项。
function unique(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) { //第一个等同于第二个,splice方法删除第二个
arr.splice(j, 1);
j--;
}
}
}
return arr;
}
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN,
'NaN', 0, 0, 'a', 'a', {}, {}
];
console.log(unique(arr))
或者利用hasOwnProperty结合类型判断来标记已存在的元素。
function unique(arr) {
var obj = {};
return arr.filter(function(item, index, arr){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}此外,还可以利用递归排序后去重的逻辑来实现。
function unique(arr) {
var array = arr;
var len = array.length;
array.sort(function (a, b) { //排序后更加方便去重
return a - b;
})
function loop(index) {
if (index >= 1) {
if (array[index] === array[index - 1]) {
array.splice(index, 1);
}
loop(index - 1); //递归loop,然后数组去重
}
}
loop(len - 1);
return array;
}
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN,
'NaN', 0, 0, 'a', 'a', {}, {}
];
console.log(unique(arr))至此,关于JavaScript数组去重的五种常用方法详解已介绍完毕。如需了解更多JavaScript数组去重相关内容,敬请查阅本站往期文章或继续阅读下文。感谢大家的支持!