【问题标题】:Difference of two 2D arrays两个二维数组的差异
【发布时间】:2019-05-26 20:40:58
【问题描述】:

我正在尝试创建函数来区分两个二维数组,但我发现要使 function removeArray() 工作,需要在两个函数中采用不同的计数器变量。如果两者都采用i,则循环只迭代一次,它应该迭代两次。

function removeArray(toremove, myarray){
      for(i=0; i< toremove.length ; i++){
          // console.log(getIndex(toremove[i],myarray));
          myarray.splice(getIndex(toremove[i],myarray),1);
          console.log("" + myarray); //only [2,3] will get remove
        }
    }
    
function getIndex(array, myarray){
      for(i=0;i< myarray.length ; i++){
          // if(typeof(array)== 'undefined'){console.log("error"); return 100;}
          if((myarray[i][0] == array[0]) && (myarray[i][1] == array[1])){
          return i;
          }
        }
    }
    var myarray=[[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]];
    var toremove=[[2,3],[3,3]];
    
    removeArray(toremove,myarray);

此外,当包含注释部分时(两者一起),即// console.log(getIndex(toremove[i],myarray))// if(typeof(array)== 'undefined'){console.log("error"); return 100}it 会在不超过两次的地方无限迭代。

为什么会这样?请帮忙。提前致谢!

【问题讨论】:

  • 这不是二维数组,而是数组的数组。 JS没有二维数组的概念。
  • 您应该使用varlet 定义计数器变量,否则它们是同一个全局变量:for (let i = 0; .......

标签: javascript function for-loop multidimensional-array scope


【解决方案1】:

问题是您没有用varlet 定义i。在这种情况下,i 是一个全局变量,由两个函数共享。

因此,当调用嵌套的getIndex 函数时,i 可能会递增直到myarray.length。然后当执行返回到第一个函数的循环中时,i 已经太大而无法继续循环。那里的循环退出,一切都完成了。

而是将i 定义为局部函数变量(var)或块变量(let),它会起作用:

function removeArray(toremove, myarray) {
    for(let i = 0; i < toremove.length; i++) {
        myarray.splice(getIndex(toremove[i], myarray), 1);
    }
}
    
function getIndex(array, myarray){
    for(let i = 0; i < myarray.length; i++){
        if (typeof(array)== 'undefined') {
            console.log("error"); 
            return 100;
        }
        if ((myarray[i][0] == array[0]) && (myarray[i][1] == array[1])) {
            console.log("found match at position " + i);
            return i;
        }
    }
}

var myarray=[[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]];
var toremove=[[2,3],[3,3]];

console.log("before: " + JSON.stringify(myarray));
removeArray(toremove,myarray);
console.log("after: " + JSON.stringify(myarray));

通常更好的做法是不要使用splice 改变数组,而是返回一个不包含要删除的项目的新副本。您可以为此使用filterevery。然后你必须将函数的返回值分配给应该有结果的数组(也可以覆盖同一个数组):

function removeArray(toremove, myarray){
    return myarray.filter(arr => 
        toremove.every(rem => arr[0] != rem[0] || arr[1] != rem[1])
    );
}
    
var myarray=[[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]];
var toremove=[[2,3],[3,3]];

console.log("before: " + JSON.stringify(myarray));
myarray = removeArray(toremove, myarray);
console.log("after: " + JSON.stringify(myarray));

【讨论】:

  • 我仍然无法理解,当getIndex(toremove[i],myarray) 被调用两次时,为什么循环会无限次迭代。
  • 想象getIndex 中的循环在某个时刻在第一次迭代中返回i == 0。然后i重置为removeArray 中的循环,它将从第一个条目重新开始......历史将无休止地重复。无论如何,不​​要为此头疼。如果你坚持使用局部变量,这将永远不会发生。
【解决方案2】:

也许 .filter 方法对你有好处

function removeArray(toremove, myarray) {
    return myarray.filter((el) => {
        for (let i in toremove) {
            if (toremove[i][0] === el[0] && toremove[i][1] === el[1]) {
                return false;
            }
        }
        return true;
    });
}

var myarray=[[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]];
var toremove=[[2,3],[3,3]];
    
console.log(removeArray(toremove,myarray));

【讨论】:

  • 感谢回复。但我想知道为什么两个函数中的计数器变量保持相同时会出现问题
【解决方案3】:

它正在迭代一次,因为您的代码遇到了错误。 javascript 总是通过引用传递变量。可以参考this了解

Uncaught TypeError: Cannot read property '0' of undefined on line 16

你可以使用下面的逻辑来避免错误

function removeArray(toremove, myarray){
  let indexes = []
  for(i=0; i < toremove.length ; i++){
    indexes.push(getIndex(toremove[i],myarray))
  }
  for (var i = indexes.length -1; i >= 0; i--)
    myarray.splice(indexes[i],1);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    相关资源
    最近更新 更多