数组去重算法,改了个地方就跑不通了,浏览器卡死,但不知道问题在哪?

原本的正确写法:

clipboard.png

我改了之后的:

clipboard.png

箭头部分是改动的。

源代码:
正确写法:

    var ary=[1,2,34,56,6,7,45,3,2,2,12,4,9,8,6,7,4];
    function deleteRepeat(ary){
        var obj={};
        for(var i= 0,len=ary.length;i<len;i++){
            var temp=ary[i];
            if(obj[temp]==temp&&temp!=undefined){
                ary.splice(i,1);
                i--;
                continue;
            }
            obj[temp]=temp;
        }
        obj=null;
        return ary;
    }
    var newAry=deleteRepeat(ary);
    console.log(newAry);

改过之后:

    var ary=[1,2,34,56,6,7,45,3,2,2,12,4,9,8,6,7,4];
    function deleteRepeat(ary){
        var obj={};
        for(var i= 0,len=ary.length;i<len;i++){
            var temp=ary[i];
            if(obj[temp]){             //试了下,如果把这里改成if(obj[temp]&&temp!=undefined),就能正确运行,但我不知道这样写的用处。按理来说,如果temp=undefined,obj[temp]也就等于undefined了,后面的代码根本不会执行
                ary.splice(i,1);
                i--;
                continue;
            }
            obj[temp]=1;
        }
        obj=null;
        return ary;
    }
    var newAry=deleteRepeat(ary);
    console.log(newAry);
阅读 3.3k
6 个回答

谢邀~

又++ 又-- 死循环了呗,
如果不判断 arr[i]!=undefined 空数组的时候就会死循环,
比如测试用例:
[1,1,1,1];

真逗, 请问是哪位踩得我, 哪句说的不对?
题主问的
服务器卡死是为什么? 除了我有一个人说的是为什么卡死吗?

既然这么不开窍,
我再解释一下为什么会死循环~

还是拿测试用例[1,1,1,1];

第一次循环对应数组index为0 value为1
第一次进来obj肯定为空, 缓存一个{1: 1};

第二次循环数组index为1 value为1;
判断出有一个value为 1(obj : {1: 1});
则对数组删除index为1的数据.
同时对i--, 当进入下一次循环的时候i又++, 所以可以理解到下次循环i不变,i为1

第三次循环同理,i为1

第四次进入循环时i为1,
但是arr的长度为1,则 arr[1]为undefined,
但是没有判断是否为undefined,
直接判断obj[undefined]因为不存在直接跳出到
obj[temp]=1;此时temp为undefined
即为把obj声明一个属性为undefined值为1
Object {1: 1, undefined: 1}

第五次循环
i为2
同样数组中只有一个值所以arr[i]还是undefined;
但是obj[undefined]为1,
所以再去删除数组, (当前数组为空);
同时i--;

直到正无穷~

ary.splice会改变数组长度,后面使用i--来更新当前指针位置

for循环中 var i= 0;i<ary.length;i++这里的ary.length会计算新的数组长度,循环完也就处理完了。

for循环中 var i= 0,len=ary.length;i<len;i++这里的len不会发生变化。遇到与前面重复的数字删除后执行了i-1,当实际处理完ary时i是小于len的,这时temp=ary[i]为undefined,如果整个数组只有一个需要删除的元素时,多执行一次i就等于len了不会出错。超过一个需要删除时,经过一次赋值后obj['undefined']为1,然后就一直执行for的加后if里面的减,当判断完最后一个的时候还在执行循环。

你说的obj[temp]也就等于undefined了,后面的代码根本不会执行。仅限于if里面的不执行。后面obj[temp]=1是会执行的,下一次就死循环了

<script>
var ary=[1,2,34,56,6,7,45,3,2,2,12,4,9,8,6,7,100];
    function deleteRepeat(ary){
        var obj={};
        for(var i= 0;i<ary.length;i++){
            var temp=ary[i];
            if(obj[temp]){             //试了下,如果把这里改成if(obj[temp]&&temp!=undefined),就能正确运行,但我不知道这样写的用处。按理来说,如果temp=undefined,obj[temp]也就等于undefined了,后面的代码根本不会执行
                ary.splice(i,1); 
                i--;
                continue;
            }
            obj[temp]=1;
        }
        obj=null;
        return ary;
    }
    var newAry=deleteRepeat(ary);
    console.log(newAry);
</script>

没毛病呀,我这边完美运行诶。

    function arr(arr) {
        var obj = {};
        for (var i = 0; i < arr.length; i++) {
            var temp = arr[i];
            if (obj[temp]) {
                arr.splice(i, 1);
                i--;
                continue;
            }
            obj[temp] = 1;
        }
        obj = null;
        return arr;
    }
    var a = [1,2,3,2,4,3,5,6,7,4,1];
    console.log(arr(a));

怎么感觉被报复了呢????

clipboard.png

我觉得你应该给len也--

len=ary.length;i<len

因为你在for中删除了数组元素,len 已经不是 length 了

var i= 0,len=ary.length;i<len;i++//len被写死了..而arr.length是变化

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题