JavaScript中的array.splice()方法无法从数组中移除元素?

3

我有一个remove[]数组,其中包含数据数组中所有元素为0的索引位置(如下所示)。

数据数组:

Retail,1,Utilities,1,Food & Restaurant,3,No Data,4,Construction,0,Non-profit,1,Financial Services,12,Technology,2,Law,3,Religion,3,Retired,2,Insurance,0,Real Estate,2,Audit,3,Business Organizations,3,Media & Marketing,0,Education,3,Transportation,0,Manufacturing,0,Entertainment & Sports,0,Architecture & Engineering,0,Cultural Institutions,0,Government,0,Banking,0,Health Care,0,Business Services,0

我的 JavaScript

   var remove =  [];          
    $.each(options.series[0].data, function(index, item) {
    if (options.series[0].data[index][1] == 0)
    {                    
        //options.series[0].data.splice(index,1);  
        remove[index] = index;                                      

    }

    for (i=0; i<=remove.length; i++)
    {
    //alert(remove);                
    if (remove[i] != undefined)
        options.series[0].data.splice(remove[i],1);

    }   

数据数组在使用splice()函数后,仍然存在许多值为0的元素。
Retail,1,Utilities,1,Food & Restaurant,3,No Data,4,Non-profit,1,Financial Services,12,Technology,2,Law,3,Religion,3,Retired,2,Insurance,0,Audit,3,Business Organizations,3,Media & Marketing,0,Education,3,Manufacturing,0,Entertainment & Sports,0,Cultural Institutions,0,Banking,0,Business Services,0

如果我将splice更改为包含替换元素。
options.series[0].data.splice(remove[i],1,'removed');

从数据数组中移除所有0元素。嗯?
Retail,1,Utilities,1,Food & Restaurant,3,No Data,4,removed,Non-profit,1,Financial Services,12,Technology,2,Law,3,Religion,3,Retired,2,removed,Real Estate,2,Audit,3,Business Organizations,3,removed,Education,3,removed,removed,removed,removed,removed,removed,removed,removed,removed

如何从数据数组中删除所有的0元素?

可能是重复的问题:在JavaScript中从数组中删除 - Rob W
看起来数组的成员应该是字符串。你没有将它们引用起来,所以它们被解释为标识符,你应该会得到错误提示——除非你没有发布真正的代码。 - RobG
6个回答

16
每次你移除一个元素,都会使得之后的缓存索引失效,因为数组从那个点开始重新索引。
结果就是,在第一个之后,你会移除错误的项。
你应该反向迭代remove数组。
var i = remove.length;
while (i--) {
    if (remove[i] != undefined)
        options.series[0].data.splice(remove[i],1);
}   

此外,如果您只是将每个索引推入remove数组中,您可以提高性能并摆脱undefined测试。
remove.push(index);

1
如果存在一对一的交换,它也应该正向工作,因为插入的元素替换了删除的元素,索引不受影响。否则,是的,它应该向后完成。 - RobG
@RobG: 插入的元素是工作代码的一部分。OP说明插入可以解决问题,但不想要插入。编辑:看到您的更新...是的,只要有插入,它就可以工作。 - user1106925
太好了,它有效了。我还想知道如何在remove[]中摆脱未定义的值。你读懂了我的心思并回答了:)。 - imObjCSwifting
@EverydayImSeeSharping:很高兴它起作用了。 :) 顺便说一下,除非您还有另外一个使用remove数组的方法,否则您可以直接反向迭代options.series [0] .data数组,并在那里执行splice() - user1106925
1
@amNot - 打字时有些分心。 :-) - RobG

1

我的问题是splice从数组中删除了错误的元素。我看到了使用while循环的答案,但我想出的解决方案是:

var index = jQuery.inArray(element, arr);
arr.splice(index,1);

0

如果您想从一个数组中删除所有元素,最好不要使用splice,而要使用length

options.series[0].data.length = 0;

请参见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length

更新:

我误解了问题。在您的情况下,我可能会过滤掉值为零的元素,而不是进行两次循环(一次用于收集它们,一次用于删除它们)。因此,可以尝试以下代码:

function isNotZero(item) {return item[1] !== 0}

var filtered = options.series[0].data.filter(isNotZero);

options.series[0].data = filtered;

请参见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

如果您想要支持的浏览器不实现ES5,我建议您为所有es5方法使用shim(在该页面中有一个用于filter的shim),或者使用类似underscore的库。


并非所有元素都被删除。OP正在构建一个具有值“0”的元素索引列表,并仅删除这些元素。 - user1106925

0

如果您查看原始数组和第一个结果数组,您会注意到非0元素已被删除。从我的观察中可以看出问题是,您的数组remove正在寻找已经移动一个位置向左的索引,因为之前的一些索引已经被删除了。您需要在最终的for循环中添加一个纠正调整,或者采用另一种方法来解决这个问题。


0

我认为你可以这样很快地完成它:

var dataArr = ["Retail",1,"Utilities",1,"Food & Restaurant",3,"No Data",4,"Construction",0,"Non-profit",1,"Financial Services",12,"Technology",2,"Law",3,"Religion",3,"Retired",2,"Insurance",0,"Real Estate",2,"Audit",3,"Business Organizations",3,"Media & Marketing",0,"Education",3,"Transportation",0,"Manufacturing",0,"Entertainment & Sports",0,"Architecture & Engineering",0,"Cultural Institutions",0,"Government",0,"Banking",0,"Health Care",0,"Business Services",0];

var item = 0; // value of the item to remove

while (dataArr.indexOf(item) > -1) {
 dataArr.splice(dataArr.indexOf(item), 1);
}

console.log(dataArr);

0
我使用一个名为DevBox.Linq.JS的库。
它基本上为Javascript数组添加了Linq类型的功能。例如,它添加了“Remove”:
   Array.prototype.Remove = function (condition) {
    if (condition == undefined) {
        console.error('Informe a expressão para executar a tarefa.')
        return;
    }

    for (var i = 0 ; i < this.length ; i++) {
        if (condition(this[i]))
            this.splice(i, 1);
    }
}

这样你就可以像这样使用lambda:

myArray.remove(i=>i=="valueToDelete");

希望这有所帮助,它已经具备了所有功能,因此您不必处理那个讨厌的splice。

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