循环以删除多次出现的数组中的元素

Edu*_*eno 21 javascript arrays

我想删除一个带有函数多次出现的数组中的元素.

var array=["hello","hello","world",1,"world"];

function removeItem(item){
    for(i in array){
        if(array[i]==item) array.splice(i,1);
    }
}
Run Code Online (Sandbox Code Playgroud)
removeItem("world");
//Return hello,hello,1
Run Code Online (Sandbox Code Playgroud)
removeItem("hello");
//Return hello,world,1,world
Run Code Online (Sandbox Code Playgroud)

当循环重复两次时,此循环不会删除该元素,只删除其中一个元素.

为什么?

Ben*_*aum 36

您有一个内置函数filter,它根据谓词(条件)过滤数组.

它不会改变原始数组,但会返回一个新的过滤数组.

var array=["hello","hello","world",1,"world"];
var filtered = array.filter(function(element) {
    return element !== "hello";
}); // filtered contains no occurrences of hello
Run Code Online (Sandbox Code Playgroud)

您可以将其解压缩到一个函数:

function without(array, what){
    return array.filter(function(element){ 
        return element !== what;
    });
}
Run Code Online (Sandbox Code Playgroud)

但是,原始过滤器似乎足够表达.

这是其文档的链接

您的原始功能有一些问题:

  • 它使用for... in循环迭代数组,该循环无法保证迭代顺序.此外,不要使用它来迭代数组 - 更喜欢普通的for...循环或.forEach
  • 你正在使用一个一个错误来迭代一个数组,所以你要跳过下一个项目,因为你要删除元素并继续运行数组.


Veg*_*ger 8

这是因为for-loop在删除事件后转到下一个项目,因此在该项目之后直接跳过该项目.

例如,假设item1需要在此数组中删除(请注意,这<-是循环的索引):

item1 (<-), item2, item3
Run Code Online (Sandbox Code Playgroud)

删除后:

item2 (<-), item3
Run Code Online (Sandbox Code Playgroud)

更新索引后(循环结束)

item2, item3 (<-)
Run Code Online (Sandbox Code Playgroud)

所以你可以看到item2被跳过,因此没有检查!

因此,您需要通过手动将索引减少1来对此进行补偿,如下所示:

function removeItem(item){
    for(var i = 0; i < array.length; i++){
        if(array[i]==item) {
            array.splice(i,1);
            i--; // Prevent skipping an item
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

for您可以使用更多"现代"方法来过滤掉不需要的项目,而不是使用此-loop,如Benjamin另一个答案中所示.