Splice()不会使数组为空

时间:2015-08-22 22:12:03

标签: javascript arrays array-splice

我有数组x,y和z。 在迭代x时,基于条件我需要继续从z中删除元素。这就是我想要做的事情:

var x = ["test0", "test1", "test2"];
var y = ["test0", "test1", "test2"];
var z = ["test0", "test1", "test2"];

function myFunction(){
    for (var i=0; i<x.length; i++){
        for (var j=0; j<y.length; j++){
            if(x[i] == y[j]){
                z.splice(i,1);
            }
        }

    }
document.getElementById("demo").innerHTML = z;
}

在迭代结束时,z应该为空。但它始终显示我'test1'元素仍然存在。 由于正确的索引没有被拼接,我试图做z.splice(i--,1),但这也不起作用。

请告知解决此问题的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

如果您创建某种表格,这很容易理解。问题是在第一次拼接之后,z的索引与x和y的索引不同:

x[0] = j[0] : i = 0 -> z.splice(0, 1); - test0 is removed - z = ["test1", "test2"];
x[1] = j[1] : i = 1 -> z.splice(1, 1); - test2 is removed - z = ["test1"];
x[2] = j[2] : i = 2 -> z.splice(2, 1); - nothing is removed - z = ["test1"];

解决方案:

function myFunction() {
    var removed = 0; // removed items counter
    for (var i = 0; i < x.length; i++) {
        for (var j = 0; j < y.length; j++) {
            if (x[i] == y[j]) {
                z.splice(i - removed, 1); // subtract removed counter from index
                removed++; // increment removed counter
            }
        }

    }
}

答案 1 :(得分:3)

正如答案所说,你的问题是拼接 z 意味着索引和值不再在数组之间对齐。从任何类型的列表中删除元素时跟踪已删除索引的常用替代方法是从结尾迭代到开始,例如。

&#13;
&#13;
var x = ["test0", "test1", "test2"];
var y = ["test0", "test1", "test2"];
var z = ["test0", "test1", "test2"];

function myFunction(){
    for (var i=x.length; i>0; ){
        for (var j=y.length; j> 0; ){
            if(x[--i] == y[--j]){
                z.splice(i,1);
            }
        }
    }
    document.write('"' + z.join() + '"');
}

myFunction();
&#13;
&#13;
&#13;

如果你使用ES5引入的一些语法糖, reduceRight 有助于减少代码量:

function myFunction(){
  x.reduceRight(function(n, x, i) {
    y.reduceRight(function(n, y) {
      if (x == y) z.splice(i, 1)
    }, null);
  }, null)
  document.write('"' + z.join() + '"');
}

答案 2 :(得分:1)

您可以通过跟踪z中删除的元素数来解决它:

var numRemoved = 0;
for (var i=0; i<x.length; i++){
    for (var j=0; j<y.length; j++){
        if(x[i] == y[j]){
            z.splice( i - numRemoved++ , 1 );
        }
    }
}

答案 3 :(得分:0)

您可以使用indexOf()

找到当前索引,而不是跟踪移动的索引
for (var i=0; i<x.length; i++){
    for (var j=0; j<y.length; j++){
        if(x[i] == y[j]){
            z.splice( z.indexOf(x[i]) , 1 );
        }
    }
}