如何在JavaScript的foreach循环中删除特定的数组元素

8
var fruit = ["apple","pear","pear","pear","banana"];

如何从这个数组中删除所有的“pear”水果?我尝试了以下方法,但仍然有一个梨子留下:
for(var f in fruit) {
    if ( fruit[f] == "pear" ) {
        fruit.splice(f, 1);
    }
}

for(var f in fruit) {
    document.write(fruit[f]+"<br>");        
}

输出:

apple 
pear 
banana

我做错了什么?实时演示:http://jsfiddle.net/SbxHc/

2
等一下... f甚至不是一个索引(数字)! - Derek 朕會功夫
2
fruit = fruit.filter(function(f) { return f !== "pear"; }); - user1106925
10个回答

25
var fruit = ["apple", "pear", "pear", "pear", "banana"],
    i;

for (i = 0; i < fruit.length; ++i) {
    if (fruit[i] === "pear") {
        fruit.splice(i--, 1);
    }
}

console.log(fruit);
//["apple", "banana"]

谢谢!我必须像你那样使用循环吗?也可以使用foreach变体吗? - Nick
尝试使用[].forEach() - Derek 朕會功夫
4
不可能。无论如何都不应该使用for..in循环遍历数组。 - Esailija
3
在上面的代码中,无论是“++i”还是“i++”,都没有关系,以防有人想知道。 - schellmax

7
for (var i = fruit.length - 1; i > -1; i--) {
    if (fruit[i] == "pear")
        fruit.splice(i, 1);
}

2
那么 fruit[i] == "pear" 部分在哪里? - Derek 朕會功夫
哎呀,犯了个小错误,;-) - Tom

3

当你在迭代过程中从一个数组中删除元素时,通常会反向迭代,以免当前索引在删除元素时跳过其他元素:

var fruit = ["apple","pear","pear","pear","banana"];
var i;

for (i = fruit .length - 1; i >= 0; i--) {
    if (fruit [i] === "pear") {
        fruit .splice(i, 1);
    }        
}

console.log(fruit );

确实!太遗憾了,不能用for...in来完成,但我想我只是有点懒。 :P - Nick

2
如果原始数组中有很多“错误”的元素,我建议至少考虑不使用原地数组,而是将所有“正确”的元素收集到一个新数组中:
var rightFruits = [];
for (var i = 0, len = fruit.length; i < len; ++i) {
  if (fruit[i] !== 'pear') {
    rightFruits.push(fruit[i]);
  }
}

谢谢,我们以前用C#来实现这个方法。相比使用splice(),这种方法的成本更高吗? - Nick
@Derek 快问:JavaScript中的数组是如何实现的? - raina77ow
1
@Nick:不要太担心性能问题,除非涉及到大型集合。我猜当有很多删除操作时,.push()可能会更快一些,因为.splice()每次删除一个元素时都需要重新对数组进行索引从当前点开始的操作。只有通过测试才能得出准确结论。 - user1106925
1
@amnotiam 是的,你说得对;这完全取决于“坏/好”元素的比例,但splice通常是一个昂贵的操作 - 特别是如果它被重复使用,且它所作用的数组很大。 - raina77ow
回答我的问题 - push / splice 测试 - raina77ow

1
您还可以使用filter
let noPears = fruits.filter(fruit => fruit != 'pear')

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

6.4. 枚举

由于 JavaScript 的数组实际上是对象,因此可以使用 for in 语句来迭代数组的所有属性。 不幸的是,for in 不保证属性的顺序,而大多数数组应用程序希望元素按数字顺序产生。此外,仍然存在从原型链中挖掘出意外属性的问题。

幸运的是,传统的 for 语句避免了这些问题。JavaScript 的 for 语句类似于大多数类 C 语言中的 for 语句。它由三个子句控制:第一个初始化循环,第二个是 while 条件,第三个执行增量:

var i;
for (i = 0; i < myArray.length; i += 1) {
   document.writeln(myArray[i]);
}

0
如果不需要反向迭代,可以使用 while 循环和数组的 pop 函数的组合。
var daltons = [ 
  { id: 1, name: "Joe" }, 
  { id: 2, name: "William" }, 
  { id: 3, name: "Jack" }, 
  { id: 4, name: "Averell" } 
];

var dalton;
while (dalton=daltons.pop()) {
  console.log(dalton.name);
}

console.log(daltons);

0
var i; while ((i = fruit.indexOf("pear")) > -1) fruit.splice(i,1);

请注意,IE8及以下版本不支持Array.indexOf。-_-


0
为什么不倒序迭代列表呢?这样,当您从列表中删除一个元素并且长度发生变化时,它不会破坏循环逻辑:
var fruit = ["apple","pear","pear","pear","banana"];
for (var i = fruit.length - 1; i >= 0; i--) {
    if (fruit[i] === "pear") {
        fruit.splice(i, 1);
    }
}

console.log(fruit); // ["apple", "banana"]

-1
for(var f in fruit) {
    if ( fruit[f] == "pear" ) {
        fruit.splice(f-1, 1);
    }
}

for(var f in fruit) {
    document.write(fruit[f]+"<br>");        
}

享受


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