Jun*_*3ta 7 javascript loops for-of-loop
I'm trying to edit an array and remove elements that do not meet a certain condition. If I use a reverse for loop combined with .splice(index,n), the code works just fine. I'm stuck at implementing the same using the ES6 for...of loop
let array=[1,2,3];
//reverse for loop
for(var i=array.length - 1; i>=0; i--) {
if(array[i]>=2) {
/*Collect element before deleting it.*/
array.splice(i,1);
}
}
console.log(array);
// returns [1]
Run Code Online (Sandbox Code Playgroud)
Using for..of
let array=[1,2,3];
for(let entry of array) {
if(entry>=2) {
let index = array.indexOf(entry);
/*The array is being re-indexed when I apply
.splice() - the loop will skip over an index
when one element of array is removed*/
array.splice(index, 1);
}
}
console.log(array);
//returns [1,3]
Run Code Online (Sandbox Code Playgroud)
Is there a way to achieve this functionality using a for...of loop or do I have to stick to the reverse for loop
Update
I need to collect the entries that don't meet the elements removed by either the filter() or reverse for loop functions to a secondary array.
You can't reasonably use for-of for this. If you remove the "current" entry during the iteration, you'll skip the next entry, because of the way array iterators are specified (they use the index of the entry). You can see that with this contrived example:
const array = [1, 2, 3];
for (const entry of array) {
console.log(entry);
if (entry === 2) {
array.splice(1, 1);
}
}
console.log(array);Run Code Online (Sandbox Code Playgroud)
Notice how there was no loop iteration for entry 3.
I'd suggest either sticking with your reverse for loop or using filter to produce a new array containing only the entries you want to keep.
Using filter:
let array = [1, 2, 3];
array = array.filter(entry => entry < 2);
console.log(array);Run Code Online (Sandbox Code Playgroud)
I said "reasonably" above because, of course, there's always a way. You could loop through a copy of the array and maintain the index outside it:
const array = [1, 2, 3];
let index = 0;
for (const entry of [...array]) {
if (entry >= 2) {
array.splice(index, 1);
} else {
++index;
}
}
console.log(array);Run Code Online (Sandbox Code Playgroud)
That doesn't seem reasonable compared to the alternatives, unless of course there are constraints pushing you that way. :-)
根据@TJ的回答,当使用 for...of 循环时:
如果在迭代期间删除“当前”条目,则由于指定数组迭代器的方式(它们使用条目的索引),您将跳过下一个条目。
这留下了另外两个选项,使用 areverse for loop和 afilter函数。我之前提到过,在删除当前数组元素之前,我需要对其进行操作。
1. 使用.filter()函数
并参考@TJ的评论
let array = [1,2,3];
let collection = [];
array = array.filter(function(entry) {
if(entry>=2) {
collection.push(entry);
}
return entry <2;
});
console.log(collection); //returns [2,3]
console.log(array); //returns [1]
Run Code Online (Sandbox Code Playgroud)
2. 使用reverse for loop
let array = [1,2,3];
let collection = [];
for(var i=array.length - 1; i>=0; i--) {
if(array[i]>=2) {
collection.push(array[i]);
array.splice(i,1);
}
}
console.log(collection); //returns [2,3]
console.log(array); //returns [1]
Run Code Online (Sandbox Code Playgroud)
这种情况下的函数filter()需要一个额外的步骤来临时保存不满足条件的元素。它reverse for loop提供了一种更清洁的方式来实现相同的目标。