前言
最近学习着,突然发现自己心中总有些惶恐,因为发现自己写过的一些东西好像忘记了,又好像是以前就没有弄彻底,所以决定写一些代码夯实一下基础,并打消自己的顾虑,试想一个始终觉得自己基本功都不扎实的人,能在程序这条路上走得很远?万丈高楼平地起,所以基础很重要!!!这是给我自己的忠告
1、最老实的方法:双重循环
这种方法是最基本的去重方法,思路是循环数组的每一个元素,循环当前元素时,会和数组当前元素后的所有元素进行对比,找到和它重复的元素,就说明数组中有和当前正在循环元素相同的元素(即存在重复元素),所以就删除正在循环的元素,这里有两种删除思路
思路一:一次性删除数组中和当前正在循环元素相同的所有元素,第二重循环始终执行完
let arr=[1,2,3,4,1,5,5,1,2,'2'];
console.time("test")
function ArrayRemoveRepeat(arr){
for(let i=0,length=arr.length;i<length;i++){
for(let j=i+1,length=arr.length;j<length;j++){
if(arr[i] === arr[j]){
arr.splice(j,1);
j--;
}
}
}
return arr;
}
console.log(ArrayRemoveRepeat(arr)); //[ 1, 2, 3, 4, 5, "2" ]
console.timeEnd("test")
思路二:每次找到数组中有元素和当前正在循环元素重复的元素,就删除当前正在循环的元素,并使用break跳出循环
let arr=[1,2,3,4,1,5,5,1,2,'2'];
console.time("test1")
function ArrayRemoveRepeat(arr){
for(let i=0,length=arr.length;i<length;i++){
for(let j=i+1,length=arr.length;j<length;j++){
if(arr[i] === arr[j]){
arr.splice(i,1);
i--;
break;
}
}
}
return arr;
}
console.log(ArrayRemoveRepeat(arr)); //[ 3, 4, 5, 1, 2, "2" ]
console.timeEnd("test1")
下面是这种方法两种删除思路的执行时间对比:
通过对比我们发现思路二的循环效率要快一点点,这种方法的缺点在于,双重for循环,如果数组比较长,比较耗费时间
2、排序去重法
这种方法的思路就是先把要去重的数组排序,所有可能重复的元素都排在了一起,所以你可以存第一个元素到无重复元素的数组,然后循环准备去重的数组,从数组索引1开始循环,因为索引0的元素已经存到了无重复元素的数组里面,你只要比较当前正在循环的元素和无重复元素数组的最后一位元素是否相同,如果相同,就继续下一次循环,如果不相同,就把当前正在循环的元素加到无重复元素的数组
let arr1=[1,2,3,4,1,5,5,1,2,'2'];
function ArrayRemoveRepeat1(arr){
arr.sort();
let arrCompare=[arr[0]];
for(let i=1,length=arr.length;i<length;i++){
if(arr[i]!==arrCompare[arrCompare.length-1]){
arrCompare.push(arr[i]);
}
}
return arrCompare;
}
console.log(ArrayRemoveRepeat1(arr1)) //[ 1, 2, "2", 3, 4, 5 ]
这种去重方式思路比较发散,但是缺点也比较明显,就是要先将待去重的数组排序,如果你本意只是想当初的去重,并不想排序,可能这种方式就不太适合
3、对象去重法
这种去重方法的思路是拿一个对象的减去存数组的元素,利用对象键的唯一性,如果对象的键对应的键值不存在,则该元素不是重复元素,将该元素添加到无重复元素数组,并将该元素作为对象的键存储,该元素作为键对应的键值为true,表示该元素已经添加到无重复元素数组中了
let arr2=[1,2,3,4,1,5,5,1,2,'2'];
function ArrayRemoveRepeat2(arr){
let obj={};
let res=[];
for(let i=0,length=arr.length;i<length;i++){
if(!obj[arr[i]]){
res.push(arr[i]);
obj[arr[i]]=true;
}
}
return res;
}
console.log(ArrayRemoveRepeat2(arr2));//[ 1, 2, 3, 4, 5 ]
这种方式,只进行了一次循环,效率比较高,但是它也有它的问题,细心的同学可能已经发现了,数组元素字符串的2也被去掉了,只是为什么?熟悉对象的都知道,标准对象的键都是字符串,所以字符串2和数字2作为对象的键被认为是相等的,所以导致字符串2也被去除了
4、利用ES6的数据结构set去重
这种去重方式的思路是利用set数据结构能够自动去除重复元素
let arr3=[1,2,3,4,1,5,5,1,2,'2'];
function ArrayRemoveRepeat3(arr){
let set=new Set(arr); //将数组作为参数传入set结果,进行去重
arr=Array.from(set); //利用Array.from将set结构转换成数组
return arr;
}
console.log(ArrayRemoveRepeat3(arr3)); //[ 1, 2, 3, 4, 5, "2" ]
5、利用数组的indexOf方法去重
这种去重方法的思路是循环数组的每一个元素,然后用正在循环的元素去无重复元素的数组里面进行查找,看无重复元素的数组里面是否有这个元素,如果没有这个元素,则加该元素添加到无重复元素的数组中,这方法类似于字符串的indexOf方法
let arr4=[1,2,3,4,1,5,5,1,2,'2'];
function ArrayRemoveRepeat4(arr){
let res=[];
for(let i=0,length=arr.length;i<length;i++){
if(res.indexOf(arr[i])===-1){
res.push(arr[i]);
}
}
return res;
}
console.log(ArrayRemoveRepeat4(arr4))//[ 1, 2, 3, 4, 5, "2" ]
6、利用高阶函数filter方法
let arr5=[1,2,3,4,1,5,5,1,2,'2'];
const arr=arr5.filter(function(ele,index,array){
return index===array.indexOf(ele)
})
console.log(arr) //[ 1, 2, 3, 4, 5, "2" ]
元素索引和元素第一次出现在数组中的索引一致,则表明元素是第一次出现,就把该元素过滤出来放到去重之后的数组里面
7、我有话说
可能我们用第一种方法比较多,因为它也是最容易想到的方法,但是我们应该去尝试和总结更多的方法,学习也是一样,在这里告诫自己:多尝试,多思考,多总结