JS-数组去重
数组去重
一、双for循环方式
let arr = [1,2,3,4,5,4,2,7,3,7,1];
//1、双for循环方式
for(let i = 0;i<arr.length;i++){
for(let j = i+1;j<arr.length;j++){
if(arr[i] === arr[j]){
//将随后一项放到j的位置,然后把最后一项删除
//这样不会导致索引前置,可提高性能
arr[j] = arr[arr.length-1];
arr.pop();
// arr.length--
j--;
}
}
}
console.log(arr);
splice引起的数组塌陷问题
在删除重复项后,后面每一项的索引都会向前提一位,这样(如果删除的这一项后面还有1000万项,那么这1000万项的索引都要向前提一位),这样会大大的消耗性能。
解决:我们用最后一项替换删除项,再删除最后一项(下一轮循环还要从当前项开始),这样就不会导致索引前置,从而达到优化性能的目的。
二、对象键值对的方式
let obj = {};
for(let i = 0;i<arr.length;i++){
if(obj[arr[i]]!==undefined){
arr[i] = arr[arr.length-1];
arr.pop();
i--
}else{
obj[arr[i]] = arr[i];
}
}
console.log(arr);
优点:
只有一个循环,所以性能很好
缺点:
1.如果数组中出现对象则会存在问题,因为对象的属性名不能是对象,遇到会转换为字符串;
2.如果数组中存在数字10和字符串'10',则也会认为是重复的,因为对象中的属性名是数字和字符串没有区别的;
3.数组中的值如果是undefined可能也会出现问题....
三、indexOf
let newArr = [];
arr.forEach((item,index,arrt)=>{
if(newArr.indexOf(item) === -1){
newArr.push(item);
}
})
console.log(newArr);
缺点
indexOf低版本浏览器不兼容
四、ES6新特性:Set方式
Set数据结构会自动去重
let newArr = Array.from(new Set(arr));
let newArr = [...new Set(arr)];
console.log(newArr);
缺点
低版本浏览器不兼容