JavaScript:通过传递的参数从数组中消除元素

时间:2017-06-29 07:30:59

标签: javascript

从freeCodeCamp处理挑战,我必须创建一个接受array和其他一些参数的函数。如果传递的数组中的元素与传递的参数之一匹配,则必须从数组中删除它。

我已编写此代码,但它并不适用于所有测试:

function destroyer(arr) {

  var args = Array.prototype.slice.call(arguments);

  for(i=0; i<arr.length; i++){
    for(var j=0; j<args.length; j++){
      if(args[j]===arr[i]){
        arr.splice(i,1); 
      }
    }
  }  
  return arr;
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);

步骤1:将参数对象转换为数组,因此我可以将其视为一个。 步骤2:运行嵌套for循环以查找传递的数组和传递的参数数组之间的任何匹配项。 第3步:如果找到匹配项,请使用.splice(i,1)将其删除。

不应该这样做吗?我究竟做错了什么?

编辑:这是失败的测试示例:

destroyer([3, 5, 1, 2, 2], 2, 3, 5)应该返回[1]

2 个答案:

答案 0 :(得分:4)

您正在迭代它时更改数组。因此,在第一个splice指数发生变化之后。

您可以使用filterindexOf来执行此操作。

function destroyer(array) {
  var toRemove = [].slice.call(arguments, 1);
  
  return array.filter(function(item) {
    return toRemove.indexOf(item) === -1
  })
}

console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5))

如果您仍想使用for循环。但请记住splice变异数组。所以你的函数确实会改变通常应该避免的参数。

function destroyer(arr) {

  var args = Array.prototype.slice.call(arguments);

  for(var i=0; i<arr.length; i++){
    for(var j=1; j<args.length; j++){
      if(args[j]===arr[i]){
        arr.splice(i,1);
        i--; // manually reduce index
      }
    }
  }  
  return arr;
}

console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5));

答案 1 :(得分:1)

问题在于,每次从arr中删除项目时,您的循环都会跳过下一项。想象一下,你正在迭代以下数组:

['a', 'b', 'c', 'd', 'e']

假设您处于迭代2,对应于数组中的'c'项,并删除该项。你的数组现在看起来像这样:

['a', 'b', 'd', 'e']

现在'd'将对应当前的迭代2,但您的for lopp将继续下一次迭代,3'd'项将永远不会被处理。

由于数组正在被修改,我建议改为使用while循环:

var i = 0;
while (i < arr.length){
  for(var j=0; j<args.length; j++){
    if(args[j]===arr[i]){
      arr.splice(i,1); 
    } else {
      i++;
    }
  }
}

此处,如果您删除了该项,则i不会增加,因为这意味着下一个项目已移至当前位置i