When you iterate over the values ​​of the JS array and delete the 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--; } } 

The code above takes an array of arbitrary length and checks each value. If the value of an array bit satisfies an arbitrary condition (in this case, if it is odd), then it is deleted from the array.

Array.prototype.splice() used to remove the value from the array, and then i reduced to take into account the rest of the values ​​in the "move down" array to fill in the gap that left the deleted value (so the loop does not skip the value).

However, the for loop ends when i is equal to the length of the array, which becomes shorter as values ​​disappear.

Does the value of myArray.length dynamically decrease as the loop goes through or does it keep the value at the beginning of the loop and does not update as the values ​​are deleted? If the last, what can I do to fix my cycle?

Thanks!

+7
javascript arrays for-loop
source share
5 answers

myArray.length changed using an array operation. But the cycle and splicing lead to undesirable results if they do not meet the requirements.

To prevent unnecessary corrections, use the while loop from the end to save the rest of the array for processing.

 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); 
+3
source share

The length property is read at each iteration, and the splicing method updates its value, so it works as you expected. However, I would say that this is not a good coding practice, while much more readable, so this should be an obvious choice.

To answer the question directly: you do not need to use while instead of for , but you definitely should.

0
source share

Use Array.filter instead

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

Here you want to use Array.prototype.filter() if you do not have to completely modify the original array in place.

As you suspect, the .length property of the array is updated every time you splice() . The filter() method was created for this kind of operation.

 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); 

A more concise version of the code above:

 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); 

An even more concise version based on the ES6 arrow syntax:

 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); 

And, if you MUST completely edit the array in place / use splice() here, I would recommend using Array.prototype.forEach() in a for or while . forEach() is another higher order method that allows you to implement the same functionality with fewer templates. As with most higher-order methods / functions, you can focus on determining what you need to do, rather than how to do it.

 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); 
0
source share

You can use both of them, and it depends on which one you like. if you prefer to use while loop , then Nina answer looks good, and if you want to use for loop , then think about how to completely control the changes of the counter or when the length changes

 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); 
0
source share

All Articles