JS系列:js多种高性能的数组去重方法

数组去重

var ary = [1,2,1,3,2,3,4,5,6,2,1];

解决方案1 for循环

   var ary = [3,2,3,2,2];
   //1.分别取出数组中的每一项(排除最后一项:最后一项后面没有需要比较的内容)
     2.逐个与后面的每一项进行比较
     3.遇到相同的,我们把这个重复项在原有数组中删除掉(splice)
     //i<ary.length - 1 :不用拿出最后一项
     //i是外层循环,k是里层循环
     /*=>解析:
      i=0 item=3  k=1第一轮ary[k]=2  if(3===2){删除}
                  k=2第一轮ary[k]=3  if(3===3){删除} 执行splice原有数组改变 splice(2,1) =>删除之前[0:3,1:2,2:3,3:2,4:2]
                =>删除之后[0:3,1:2,2:2,3:2]基于splice删除,会把数组改变,原有数组的内容索引都要进1
                 k=3第一轮ary[k]=2  if(3===2)...
      i=1 第二轮 item=2
          k=2 第一轮 ary[k] if(2===2)... 删除之前[0:3,1:2,2:2,3:2]
                                        删除之后[0:3,1:2,2:2]
          k=3循环结束
      i=2 第三轮 循环结束                               
              */ 
   for(var i=0;i<ary.length - 1 ; i++){
     var item =ary[i]; //=>依次拿出每一项
     //=>item: 依次拿出每一项
     //=>i: 当前拿出项的索引
     //=>k=i+1 k和当前项后面的每一项比较:起始索引应该是i+1
     for (var k=i+1; k<ary.length; k++){
     //ary[k]: 后面需要拿出来和当前项比较的这个值
        if(item === ary[k]){
          //=>相等:重复了,我们拿出来的k这个比较项在原有数组中删除
          ary.splice(k, 1) //删除后不能让k累加了
          //这样导致数组坍塌问题,当我们把当前项删除后,后面的每一项都要向前进一位,也就是原有数组的所有发生了改变,此时我们k继续累加,下一次在拿出来的结果就会跳过一位
          k--;  //=>删除后先减减,在加加的时候相当于没加没减
       }
    }
  }  
  console.log(ary)  => (6) [1, 2, 3, 4, 5, 6]

=>这种方法不适合大量的数据,上万条数据

基于对象的属性名不会重复的方法

var ary=[1,2,3,2,2,3,4,3,4,5]
 /*
 * 基于对象的属性名不能重复,我们实现高性能的数组去重
 * 1.创建一个空对象
 * 2.依次遍历数组中每一项,把每一项存储的值,当做对象的属性名和属性值存储起来
 * 
 * 第一次循环1 {1:1}
 * 第一次循环2 {1:1,2:2}
 * 第一次循环3 {1:1,2:2,3:3}
 * 第一次循环4 我们存储之前做一个判断,判断当前对象是否已经存在这个属性名了,如果存在,说明之前有这一项的存储的操作,进一步说明之前数组中出现过这个数值了(也就是重复了,此时我们把这个当前项在数组中移除即可)

//如果判断对象中是否存在这个属性:如果没有这个属性,获取的属性值是undefined
*/
var obj = {};
for(var i=0;i< ary.length; i++){
  var item = ary[i]; //每一次循环从数组中拿出来的每一项
  //存储之前需要做判断:如果对象中已经存在这个属性了,说明当前item在之前出现过,也就是当前项重复了,我们把当前项删除
  if(typeof obj[item] !== 'undefined'){
   /* ary.splice(i,1);
    i--;
   //这种删除方式不好,如果数组很长,删除某一项,后面索引都要重新计算,非常消耗性能
 */
   // =>高性能的方法:
   /* 
    * 1. 我们把数组最后一项的结果获取到,替换当前项内容
    * 2. 在把最后的一项删除
    * [12,23,34,56] 想要删除23
    * 先让56替换23 [12,56,34,56]
    * 先把最后一项删除 [12,56,23] 
    */
    ary[i] = ary[ary.length - 1];
    ary.length--;
    i--;
    continue;
}
//把这一项作为对象的属性名和属性值存储进去
obj[item] = item; //=>obj[1]=1 =>{1:1}
}
consoloe.log(ary);

es6中 new set方法

var ary=[1,2,3,2,2,3,4,3,4,5];
new Set(ary)
=> Set(5) {1, 2, 3, 4, 5}

Array.from(new Set(ary)) 方法

 var ary=[1,2,3,2,2,3,4,3,4,5];
 Array.from(new Set(ary))
=>(5) [1, 2, 3, 4, 5]

var ary=[1,2,3,2,2,3,4,3,4,5];
var newAry=Array.from(new Set(ary))
newAry
=>(5) [1, 2, 3, 4, 5]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值