数组去重

// 基于对象键值对方式
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}
 *  第四次循环 2  我们在存储之前做一个判断,判断当前对象中是否已经存在这个属性名了,如果存在,说明之前有这一项存储的操作,进一步说明之前数组中出现过这个数值了(也就是重复了,此时我们把当前项在数组中移除即可)
 *  ...
 *
 *  如何判断对象中是否存在这个属性:如果没有这个属性,获取的属性值是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,34]
         */
        ary[i] = ary[ary.length - 1];
        ary.length--;
        i--;
        continue;
    }
    //=>把这一项作为对象的属性名和属性值存储进去
    obj[item] = item;//=>obj[1]=1 =>{1:1}
}
console.log(ary);

//双重循环去重
var ary = [1, 2, 3, 2, 2, 3, 4, 3, 4, 5];

/*--解决方案一--*/
/*
 * 1.依次拿出数组中的每一项(排除最后一项:最后一项后面没有需要比较的内容)
 * 2.和当前拿出项后面的每一项依次比较
 * 3.如果发现有重复的,我们把找到的这个重复项在原有数组中删除掉(splice)
 */
//=>i<ary.length-1:不用拿最后一项
for (var i = 0; i < ary.length - 1; i++) {
    var item = ary[i];
    //=>item:依次拿出的每一项
    //=>i:当前拿出项的索引
    //=>和当前项后面的每一项比较:起始索引应该是i+1  k < ary.length找到末尾依次比较
    for (var k = i + 1; k < ary.length; k++) {
        //ary[k]:后面需要拿出来和当前项比较的这个值
        if (item === ary[k]) {
            //=>相等:重复了,我们拿出来的K这个比较项在原有数组中删除
            // ary.splice(k, 1);
            /*
             * 这样做会导致数组塌陷问题:当我们把当前项删除后,后面每一项都要向前进一位,也就是原有数组的索引发生了改变,此时我们k继续累加1,下一次在拿出来的结果就会跳过一位
             * 原数组 [1,2,3,4]
             * i=1 =>2 我们把这一项干掉,然后i++,i=2
             * 原数组 [1,3,4]
             * i=2这一项是4,3这一项就错过了
             * ...
             */
            ary.splice(k, 1);//=>删除后不能让k累加了
            k--;//=>删除后先减减,在加加的时候相当于没加没减
        }
    }
}
console.log(ary);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值