如何使用forEach在列表中删除一个元素?

34
var people = ['alex','jason','matt'];

people.forEach(function(p){
    if(p.length > 4){
       //REMOVE THIS PERSON or pop it out of the list or whatever
    }
});

console.log(people) //should return ['alex','matt']

我想使用这个forEach循环从列表中删除一个元素。


1
我不相信你应该在循环遍历列表时修改它。 - Rafe Kettler
2
你尝试过什么?SO主要是用来解决问题的,而不是一个课堂。 - Lightness Races in Orbit
2
我赞同Rafe和Tomalak的评论。关于Rafe所说的,删除for each循环内的元素并不是正常的做法(虽然我不确定JavaScript如何处理它;也许它会起作用)。你最好使用标准的基于索引的for循环;我建议从最后一个元素开始向后循环,这样你就可以删除元素而不必调整索引变量。查看MDN Array文档以获取有关Array方法的详细信息。 - nnnnnn
5个回答

62

使用合适的工具完成相应的工作。在这种情况下:

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

另外,如@nnnnnn所建议的,可以倒序循环:

for (var i = data.length-1; i >= 0; i--) {
    if (data[i].value === 5) {
        data.splice(i, 1);
    }
}

不过,你应该考虑使用Array.prototype.filter()方法:

data = data.filter(function (e) {
    return e.value !== 5;
});

或者使用诸如lodashunderscore这样的实用函数库,它们提供了从数组中删除元素的函数:

_.remove(data, function (e) {
    return e.value === 5;
});

后两者的好处是你的代码变得更易读。


4
这是一个考虑到更改索引问题的简洁解决方案! - carl-johan.blomqvist
3
.filter 看起来非常不错。 - Luca Steeb
@Gajus FYI .filter() 不会修改数组,它会返回一个新的数组。我已经进行了编辑以反映这一点。你可能还想使用更短的 ES6 语法更新代码- data = data.filter(e => e.value !== 5); - Kip
一个反向的for循环非常高效,是最易读的过程,适用于处理大型数据集,您不想复制和破坏它。 - Jeff McMahan

32

6
在提供给forEach的回调函数中,您可以修改数组,在ES5中没有任何规定阻止您这样做。 - RobG
@Hans Engel - 为什么是<=?OP是小于4。@Mrchief - OP是“我想从列表中删除一个元素”,所以我认为意图是修改数组(大多数数组方法都是如此)。 - RobG
@RobG,OP是“> 4”-“>”的补集是“<=”。 - Jon Gauthier

1
你可以很容易地使用filter()来实现这个功能:
var people = ['alex','jason','matt'];

var shortPeople = people.filter(function(p){
    return p.length <= 4);
});

console.log(people);
console.log(shortPeople);

0
请使用Array.prototype.filter代替。

const filterByLength = (arr, len) => arr.filter(s => s.length <= len);

const people = ["jon", "alex", "jason", "matt"];
console.log(filterByLength(people, 4)); // ["jon", "alex", "matt"]


0

从 ES5 开始,ForEach 可以与索引一起使用:

data.forEach(function (element, index) {
  if (element % 2 == 0) {
    data.splice(index, 1);
  }
});

3
请注意,这段代码片段实际上无法工作 -- 如果数据是[1,28,35,444,555,666,333,424,313,303,484,464,121,12,14,88,96,108,1224,777],那么它将被转换为[1, 35, 555, 333, 313, 303, 464, 121, 14, 96, 1224, 777] - Jessica Knight
2
这是正确的,很容易理解,因此像 @Gajus 解释的那样,forEach 不是这个任务的正确方法。在您的示例中,当我们删除索引为 1(值为 28)的项目时,要分析的下一个元素是索引为 2 的值应该是35,但现在它是 444,所以会跳过 35,依此类推... - adripanico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接