如果在参数中给出,则从数组中删除元素

时间:2015-12-28 18:05:45

标签: javascript arrays

我试图抓住JavaScript(再次),到目前为止它并不顺利。

挑战:

  

将为您提供一个初始数组(驱逐舰函数中的第一个参数),后跟一个或多个参数。从初始数组中删除与这些参数具有相同值的所有元素。

为什么以下代码不会删除第二个测试用例所需的元素?

DocumentStatus

它在这里成功运作:

function destroyer(arr) {
  console.log(arguments);

  for (var array_i = 0; array_i < arr.length; array_i++){
    for (var arg_i = 1; arg_i < arguments.length; arg_i++){
      console.log("indexes", array_i, arg_i);
      if (arr[array_i] === arguments[arg_i]){
        console.log(arr[array_i], arguments[arg_i], "destroyed");
        arr.splice(array_i, 1);
        console.log(arr, arguments);
        array_i = 0;
        arg_i = 1;
      }
    }
  }
  return arr;
}

但不是在这里:

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

4 个答案:

答案 0 :(得分:3)

您正在尝试通过重置索引来补偿在此过程中删除的元素。如果从数组的 end 中删除,它的很多更简单(实际上可行)。无需重置。

&#13;
&#13;
function destroyer(arr) {

  for (var array_i = arr.length - 1; array_i >= 0; array_i--){
    for (var arg_i = 1; arg_i < arguments.length; arg_i++){
      if (arr[array_i] === arguments[arg_i]){
        arr.splice(array_i, 1);
        break;
      }
    }
  }
  return arr;
}

console.log( destroyer([2, 3, 4, 2, 3], 2, 3)  );   // [4]
console.log( destroyer([2, 3, 2, 3], 2, 3)  );      // []
&#13;
&#13;
&#13;

答案 1 :(得分:1)

问题是您在循环时修改了数组。

您可以使用过滤功能执行相同的操作:

&#13;
&#13;
function destroyer(arr) {
  var args = [].slice.call(arguments);
  return arr.filter(function(item) {
    return args.indexOf(item) == -1;
  });
}
document.getElementById('output').innerHTML = 
  JSON.stringify(destroyer([2,3,2,3], 2, 3)) + "\n" +
  
  JSON.stringify(destroyer([1,2,3,4,2,3], 2, 3))
&#13;
<pre id="output"></pre>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

使用ES5方法进行反向迭代的替代方法,并修改原始数组。

&#13;
&#13;
function destroyer(arr) {
  var rest = Array.prototype.slice.call(arguments, 1);
  rest.forEach(function(unwanted) {
    var index = arr.indexOf(unwanted);
    while (index > -1) {
      arr.splice(index, 1);
      index = arr.indexOf(unwanted);
    }
  });
  return arr;
}

var initial1 = [2, 3, 2, 3];
destroyer(initial1, 2, 3);
document.getElementById('out1').textContent = JSON.stringify(initial1);
console.log(initial1);

var initial2 = [3, 5, 1, 2, 2];
destroyer(initial2, 2, 3, 5);
document.getElementById('out2').textContent = JSON.stringify(initial2);
console.log(initial2);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<pre id="out1"></pre>
<pre id="out2"></pre>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

这里的问题是你依靠长度循环遍历数组元素,同时你正在重新排列数组的元素。 所以发生的事情是在移除2和3后,2再次来到第0位,你的计数器现在领先,并且永远不会覆盖第0位。因此,还有其他情况,你将无法获得所需的结果。

所以代替这个尝试只循环每个参数一次, 选择一个参数,然后在数组中搜索它。

for(var i = 1; i < arguments.length; i++)
{
    var index = arr.indexOf(arguments[i]);
    while(index > -1)
    {
        arr.splice(index, 1);
        index = arr.indexOf(arguments[i]);
    }
}

你会得到你想要的东西。