8

我正在尝试编辑数组并删除不满足特定条件的元素。如果我使用reverse for loop组合 with .splice(index,n),则代码可以正常工作。我坚持使用 ES6for...of循环实现相同的功能

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]

使用 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]

有没有办法使用for...of循环来实现这个功能,还是我必须坚持reverse for loop

更新
我需要将不符合filter()orreverse for loop函数删除的元素的条目收集到辅助数组中。

4

3 回答 3

9

你不能合理地使用for-of它。如果您在迭代期间删除“当前”条目,您将跳过下一个条目,因为数组迭代器的指定方式(它们使用条目的索引)。您可以通过这个人为的示例看到这一点:

const array = [1, 2, 3];
for (const entry of array) {
    console.log(entry);
    if (entry === 2) {
        array.splice(1, 1);
    }
}
console.log(array);

注意 entry 没有循环迭代3

我建议要么坚持你的反向for循环,要么使用filter生成一个只包含你想要保留的条目的新数组。

使用filter

let array = [1, 2, 3];
array = array.filter(entry => entry < 2);
console.log(array);


我在上面说“合理”是因为,当然,总有办法。您可以遍历数组的副本并维护index它的外部:

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

与替代方案相比,这似乎不合理,除非当然有限制因素推动你这样做。:-)

于 2019-09-02T08:19:51.570 回答
4

根据@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]

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] 

这种情况下的filter()函数需要一个额外的步骤来临时保存不满足条件的元素。提供了一种更清洁的reverse for loop方式来实现相同的目标。

于 2019-09-02T09:13:49.213 回答
2

迭代器在删除数组中的当前条目时跳过下一个条目。所以你应该这样来达到你想要的结果。

let array = [1,2,3];
let array_new = [1,2,3];
for(let entry of array) {
if(entry>=2) {
    let index = array_new.indexOf(entry);
    array_new.splice(index, 1);
}
} 
console.log(array_new);
//returns [1]
于 2019-09-02T09:06:19.540 回答