我正在检查一组文本条目,看它们是否符合邮政编码格式。这是我的代码:
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"]
为什么不检查某些条目?
答案 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处的成员,依此类推。因此,每次拼接一个成员时,都会跳过下一个成员。
解决方案是从结束而不是从头开始迭代,因此拼接不会导致这种影响。