当前位置:嗨网首页>书籍在线阅读

31-列表变动时索引递减

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

4.3.4 列表变动时索引递减

当在循环一个列表的同时还在修改它,情况就变得有趣了。因为当列表修改时,需要相应的修改循环终止条件。最好的情况是循环的结果不是你想要的;最糟糕的情况是这个循环永远不会结束。常见的做法是使用索引递减的循环方式,也就是循环顺序由终止的地方开始,到起始位置结束。这时,如果列表有增删操作,就不会影响循环终止条件。

比如,从 bigArrayOfNumbers 中删除所有质数。使用数组中的splice方法给数组添加或者删除一个元素(详情见第8章)。下面代码就不会达到预期的效果:

for(let i=0; i<bigArrayOfNumbers.length; i++) {
    if(isPrime(bigArrayOfNumbers[i])) bigArrayOfNumbers.splice(i, 1);
} 

因为索引是递增的,而程序执行中还在删除元素,所以循环的时候很可能跳过一些素数(如果它们是相邻的)。可以通过索引递减来解决这个问题:

for(let i=bigArrayOfNumbers.length-1; i >= 0; i--) {
    if(isPrime(bigArrayOfNumbers[i])) bigArrayOfNumbers.splice(i, 1);
} 

这里要小心循环的起始和判断条件:索引必须从比数组长度小一的位置开始,因为数组下标是从零开始的。同时,当i大于或等于0时继续循环;否则会漏掉第一个元素(如果第一个元素恰好是素数,结果就会出问题了)。