数组去重的N种方法(10+)

2020-02-16  本文已影响0人  isSunny

2020注定是个让人无法忘怀的一年,这个年过的不知道怎么说,简单来说一个字“宅”,虽然平时也很宅吧,但是说实在的,这样被困在家里不能出门,出了门又必须戴口罩的日子,着实让我很是抑郁。。。最近不能返京工作,一个人在老家的老房子里,平时不会做饭的自己经过十几天的折磨,也快成了一个居家小能手了。当然了,敲代码这件事还是不能落下,疫情过后还得继续靠它吃饭呢。。。

好了,闲话说了一堆,切入正题吧。数组去重是我们不管是工作还是面试,出镜率最高的一道算法题。
我写的第一篇文章也是有关于数组去重的几种方法,不过这几天听了一位‘老师’的讲解,豁然开朗~~

我们要记住的不是它的每种代码怎么写,而是应该记住它解题思路,这样就变的简单了,衍生的方法也就可以说有很多种。。。

下面我就来详细的介绍一下吧:
let arr = [1,2,3,3,56,45,1,2,45,789,1,2,9];

思想一:es6,利用new Set()实现 Set对象存储任何类型的唯一值

法一:

let newArr = Array.from(new Set(arr));//利用Array.from把任意类型转换一个真正数组
console.log(newArr); 
//[1, 2, 3, 56, 45, 789, 9]

法二:

let newArr1 = [...new Set(arr)];//利用es6的...扩展符
console.log(newArr);  
//[1, 2, 3, 56, 45, 789, 9]
思想二:在数组中拿出当前项和后面的内容进行比较

法一:for循环,如果后面项里面存在当前项,那就删除当前项

for(let i=0;i<arr.length-1;i++){
      let cur=arr[i];
      let next = arr.slice(i+1);
      if(next.indexOf(cur)>-1){//
             arr.splice(i,1);
             i--;
       }
}
console.log(arr);
//[1, 2, 3, 56, 45, 789, 9]

法二:for循环,创建新数组,如果后面项里面不存在当前项,放入新数组

let newArg = [];
for(let i=0;i<arr.length;i++){
       let cur=arr[i];
       let next = arr.slice(i+1);
      if(next.indexOf(cur)==-1){//如果不包括
             newArg.push(cur);
      }
}
console.log(newArg);
//[3, 56, 45, 789, 1, 2, 9]

法三:for循环,如果后面项里面存在当前项,把数组最后一项替换当前项,删除最后一项

for(let i = 0;i<arr.length-1;i++){
     let cur = arr[i];
     let next = arr.slice(i+1);
     if(next.includes(cur)){//如果存在,把数组最后一项替换当前项,删除最后一项
          arr[i]=arr[arr.length-1];
          arr.length--;
          i--;
     }
}
console.log(arr);
//[9, 789, 2, 3, 56, 45, 1]

法四:for循环,如果后面项里面存在当前项,把当前项变成null,然后利用filter过滤

 for(let i = 0;i<arr.length-1;i++){
       let cur =arr[i];
       let next = arr.slice(i+1);
       if(next.includes(cur)){
            arr[i]=null; 
       }
}
arr = arr.filter((item)=>{
     return item!==null;
})
console.log(arr);
//[3, 56, 45, 789, 1, 2, 9]

法五:for循环,和法四类似 只是复制了一份新数组再过滤

let newArg = [...arr];
for(let i = 0;i<arr.length-1;i++){
      let cur =arr[i];
      let next = arr.slice(i+1);
      if(next.includes(cur)){
          newArg[i] =null;
      }
}
newArg = newArg.filter((item)=> item!==null);
console.log(newArg);
// [3, 56, 45, 789, 1, 2, 9]

法六:双for循环,当前项和后面的每一项做比较,如果相同,删除相同项

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--;
           }
    }
}
console.log(arr);
// [1, 2, 3, 56, 45, 789, 9]
思想三 :创建新的数组 和原来数组每一项作对比

法一:for循环 如果新数组里不存在 就把当前项放入新数组中

let newArr = [];
for(let i=0;i<arr.length;i++){
     if(!newArr.includes(arr[i])){
         newArr.push(arr[i]);
     }
}
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]

法二:forEach 如果新数组里不存在 就把当前项放入新数组中

let newArr = [];
arr.forEach((item)=> newArr.includes(item)?'':newArr.push(item));
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]

法三:过滤 filter 如果新数组里不存在 就把当前项放入新数组中

let newArr = [];
newArr = arr.filter((item)=> newArr.includes(item)?'':newArr.push(item));
console.log(newArr);
//[1, 2, 3, 56, 45, 789, 9]

法四:利用reduce push进新数组

 arr = arr.reduce((prev,cur)=>{
     if(!prev.includes(cur)){
         prev.push(cur);
    }
    return prev;
},[]);
console.log(arr);
//[1, 2, 3, 56, 45, 789, 9]

法五:利用reduce 数组concat拼接新数组

 arr = arr.reduce((prev,cur)=>{
     if(!prev.includes(cur)){
          return prev.concat(cur);
     }else{
          return prev;
     }           
},[])
 console.log(arr);
//[1, 2, 3, 56, 45, 789, 9]

法六: 创建对象 拿数组中的每项向新容器中存储,如果已经存储过了,把当前项干掉,用最后一项替换当前项

let obj = {};
for(let i=0;i<arr.length;i++){
      let key = arr[i];
      if(obj[key]){  typeof obj[key]!=='undefined'
         arr[i] = arr[arr.length-1];
         arr.length--;
         i--;
         continue;
      }
      obj[key]=key;
}
obj=null;
console.log(arr);
//[1, 2, 3, 9, 56, 45, 789]

法七: 创建数组 拿数组中的每项向新容器中存储,如果已经存储过了,把当前项干掉,用最后一项替换当前项

let newArr = [];
for(let i=0;i<arr.length;i++){
     let item = arr[i];
     if(newArr.includes(item)){
           arr[i]=arr[arr.length-1];
           arr.length--;
           i--;
           continue;
     }
     newArr.push(item);
}
console.log(arr);
console.log(newArr);
//[1, 2, 3, 9, 56, 45, 789]
//[1, 2, 3, 9, 56, 45, 789]
思想四:先排序 然后相邻的元素进行对比

法一:for循环

arr.sort((a,b)=>a-b);
let newArr = [];
for(let i=0;i<arr.length;i++){
     let cur = arr[i];
     let next = arr[i+1]; 
     if(cur!==next){
                newArr.push(cur);
     }
}
console.log(newArr);
//[1, 2, 3, 9, 45, 56, 789]

法二:正则

arr.sort((a,b)=>a-b);
arr=arr.join('@')+'@';
let reg=/(\d+@)\1*/g,// \1* 分组引用,出现0到多次出现一样的
newArr=[];
arr.replace(reg,(val,group1)=>{
    newArr.push(parseFloat(group1));
});
console.log(newArr);
//[1, 2, 3, 9, 45, 56, 789]

恩,差不多四种思想,基本就这样吧,里面indexOf和includes可以互换也可以衍生出更多的方法,这里就不继续写了,我数了一下有十七八种了,不继续写啦~~~

最后希望这次疫情早点过去,我也好早点返京工作,武汉加油,中国加油~~~

上一篇下一篇

猜你喜欢

热点阅读