【问题标题】:Splice() does not make the array emptySplice() 不会使数组为空
【发布时间】:2015-08-22 22:12:03
【问题描述】:

我有数组 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),但这也不起作用。

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

【问题讨论】:

  • 只需像这样更新您的拼接方法参数:z.splice(0,1);它应该工作
  • @AliBaig 这只适用于这个测试用例。张贴者试图删除与其他数组匹配的索引,但这并不总是索引0。如果他们想删除所有元素,将变量分配给一个新的空数组会更容易。

标签: javascript arrays array-splice


【解决方案1】:

如果您创建某种表格,这很容易理解。问题是第一次拼接后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
            }
        }

    }
}

【讨论】:

    【解决方案2】:

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

    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();

    如果你使用 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() + '"');
    }
    

    【讨论】:

    • 我认为这是最好的解决方案。
    • 感谢大家的建议/解决方案。 charlietfl 给出的解决方案对我来说效果最好,因为我的数组 z 总是一样的。
    【解决方案3】:

    您可以通过跟踪从 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 );
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用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 );
              }
          }
      }
      

      【讨论】:

      • 这假设z[i] === x[i],如果var z = ["test2", "spaghetti", "pamplemousse"];,它的行为会有所不同
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      • 1970-01-01
      • 2016-02-19
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      相关资源
      最近更新 更多