两个2D阵列的差异

时间:2018-12-29 09:42:57

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

我正在尝试创建函数以使我区别于两个2D数组,但是我发现要使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})时,它会无限次迭代,而重复部分不应超过两次。

为什么会这样?请帮助。预先感谢!

3 个答案:

答案 0 :(得分:0)

也许.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));

答案 1 :(得分:0)

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

  

未捕获到的TypeError:无法读取第16行上未定义的属性'0'

您可以使用以下逻辑避免错误

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

答案 2 :(得分:0)

问题是您没有用ivar定义let。在这种情况下,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));