繁体   English   中英

当循环遍历JS数组的值,并且我删除了值时,我是否需要使用while而不是for?

[英]When looping through values of a JS array, and I remove value, do I need to use while instead of for?

var myArray = [1,2,3,4,5,6,7,8,9];

function isOdd(value){
    return value % 2;
}

for(var i = 0; i < myArray.length; i++){
    if(isOdd(myArray[i])){
        myArray.splice(i,1);
        i--;
    }
}

上面的代码采用任意长度的数组并检查每个值。 如果数组的位满足任意条件(在这种情况下,如果它是奇数),则从数组中删除它。

Array.prototype.splice()用于从数组中删除值,然后i递减以说明数组中其余值“向下移动”以填补删除的值留下的间隙(所以循环不会跳过一个值)。

但是,当i等于数组的长度时, for循环结束,随着值的移除,数组的长度变短。

myArray.length的值是否随着循环的进行而动态减少,还是在循环开始时保存值而不是在删除值时更新? 如果是后者,我该怎么做才能修复我的循环?

谢谢!

myArray.length随着数组上的操作而改变。 但是,如果没有适当的填充,循环和拼接会导致不需要的结果。

为了防止不必要的更正,请从末尾使用while循环,以保留数组的其余部分以进行处理。

 function isOdd(value) { return value % 2; } var myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9], i = myArray.length; while (i--) { if (isOdd(myArray[i])) { myArray.splice(i, 1); } } console.log(myArray); 

在每次迭代中都会读取length属性,并且splice方法会更新其值,因此它可以正常工作。 但是,我会说这不是一个好的编码实践, while循环更具可读性,因此它应该是显而易见的选择。

直接回答这个问题:你不必使用while不是for ,但你绝对应该

请改用Array.filter

 var myArray = [1,2,3,4,5,6,7,8,9]; myArray=myArray.filter(function(item,index) { return !(item % 2); }) console.log(myArray) 

如果您不是必须就地修改原始数组,那么您可以在这里使用Array.prototype.filter()

正如您所怀疑的那样,每次splice()时都会更新数组的.length属性。 filter()方法是为这种操作而构建的。

 var myArray = [1,2,3,4,5,6,7,8,9]; function isOdd(value){ return value % 2; } var filteredArray = myArray.filter(function(item){ return !isOdd(item); }); console.log(filteredArray); 

以上代码的更简洁版本:

 var myArray = [1,2,3,4,5,6,7,8,9]; function isEven(value){ return value % 2 === 0; } var filteredArray = myArray.filter(isEven); console.log(filteredArray); 

一个更简洁的版本依赖于ES6箭头语法:

 var myArray = [1,2,3,4,5,6,7,8,9]; var isEven = value => value % 2 === 0; var filteredArray = myArray.filter(isEven); console.log(filteredArray); 

并且,如果你绝对必须就地编辑数组/使用splice() ,我建议在forwhile循环中使用Array.prototype.forEach() forEach()是另一种更高阶的方法,它允许您以更少的样板实现相同的功能。 与大多数高阶方法/函数一样,它允许您专注于定义您需要执行的操作,而不是确切地说如何完成。

 var myArray = [1,2,3,4,5,6,7,8,9]; function isOdd(value){ return value % 2; } myArray.forEach(function(c, i, a){ if(isOdd(c)){ a.splice(i,1); } }) console.log(myArray); 

你可以同时使用它们,这取决于你喜欢哪一个。 如果您更喜欢使用while loop那么Nina的答案看起来很好,如果您想使用for loop那么请考虑完全自己管理计数器更改,或者当长度发生变化时:

 function isOdd(value) { return value % 2; } var arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]; for (var i = 0; i < arr1.length;) isOdd(arr1[i]) ? arr1.splice(i, 1) : i++; console.log(arr1); var arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]; for (var i = 0; i < arr2.length; i++) if (isOdd(arr2[i])) { arr2.splice(i, 1); i--; } console.log(arr2); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM