ForJach在Javascript中跳过条目?

时间:2015-11-05 22:28:11

标签: javascript

我正在检查一组文本条目,看它们是否符合邮政编码格式。这是我的代码:

var invZIPs;

ZIP.forEach(function(z, i) {
    console.log(z);
    console.log(ZIP);
    if(!isZIP(z)){
        invZIPs += "(" + z + ")";
        ZIP.splice(i,1);
    }
    console.log(ZIP);
});

if(invZIPs != ""){
    console.log(""Ignored unrecognized entries: " + invZIPs");
}

为了进行调试,我在检查之前和之后打印forEach条目和数组。这是我的输出。

1
["1", "2", "31833", "4", "5"]
["2", "31833", "4", "5"]
31833
["2", "31833", "4", "5"]
["2", "31833", "4", "5"]
4
["2", "31833", "4", "5"]
["2", "31833", "5"]

为什么不检查某些条目?

2 个答案:

答案 0 :(得分:4)

  

为什么不检查某些条目?

将在回调循环开始之前确定要访问的元素范围,即使您删除了您正在访问的条目,也会继续使用下一个元素。 (参见the spec。)因此,如果在迭代期间修改数组,则会产生奇怪的效果。例如,假设条目0无效;你删除它,进入1条目0,条目2条目1等等;然后循环继续进入1,并且永远不会检查(新)条目0

在这种情况下,

Array#filter可能是更好的选择。

ZIP = ZIP.filter(function(z, i) {   // Note we're assigning the new array
    console.log(z);
    console.log(ZIP);
    if(!isZIP(z)){
        invZIPs += "(" + z + ")";
        return false;               // Leave it out of the result
    }
    console.log(ZIP);
    return true;                    // Include it in the result
});

旁注:您也永远不会给invZIPs初始值。从您使用+=开始,您可能需要

var invZIPs = "";

答案 1 :(得分:0)

为了回答这个问题,第一次通过循环,索引0处的成员被测试并从数组中拼接出来,所以所有成员都被拖垮了。

在下一次迭代中,测试索引1处的成员。由于上一个循环执行了拼接并将所有内容都向下移动,因此索引1处的成员最初是索引2处的成员,依此类推。因此,每次拼接一个成员时,都会跳过下一个成员。

解决方案是从结束而不是从头开始迭代,因此拼接不会导致这种影响。