如何删除JS中参数指定的数组中的元素

How do I remove elements in an array specified by arguments in JS?

本文关键字:参数 元素 数组 JS 何删除 删除      更新时间:2023-09-26

我正在进行一项赋值,在该赋值中,我得到了一个数组和不同数量的参数。我必须从初始数组中删除所有与这些参数值相同的值。这是我的代码:

function destroyer(arr) {
  for(var i = 1; i < arguments.length; i++)
  {
      for(var j = 0; j < arr.length; j++)
      {
          if(arguments[i] == arr[j])
          {
              arr.splice(j, 1);
          }
      }
  }
  return arr;
}
destroyer([3, 5, 1, 2, 2], 2, 3, 5)

我得到了一些数组和参数模式的正确输出,但对于上面的例子,它应该只输出[1],但我的代码正在输出[1,2]。如有任何帮助,我们将不胜感激。谢谢

执行.splice()移除项目时,它会将后面的元素移动到数组中的某个位置,如果恰好也是匹配的,则会导致for循环错过下一个元素。您可以通过在删除项目后递减for循环索引来解决这个问题,或者(我最喜欢的)您可以从后到前迭代数组,这样.splice()就不会影响未来的任何迭代。

使用您的通用代码结构,以下是递减解决方案:

function destroyer(arr) {
  for(var i = 1; i < arguments.length; i++)
  {
      for(var j = 0; j < arr.length; j++)
      {
          if(arguments[i] == arr[j])
          {
              arr.splice(j, 1);
              --j;
          }
      }
  }
  return arr;
}
var result = destroyer([3, 5, 1, 2, 2], 2, 3, 5);
document.write(JSON.stringify(result));

使用您的通用代码结构,以下是反向迭代解决方案:

function destroyer(arr) {
  for(var i = 1; i < arguments.length; i++)
  {
      for(var j = arr.length - 1; j >= 0; j--)
      {
          if(arguments[i] == arr[j])
          {
              arr.splice(j, 1);
          }
      }
  }
  return arr;
}
var result = destroyer([3, 5, 1, 2, 2], 2, 3, 5);
document.write(JSON.stringify(result));


您还可以使用其他阵列助手函数来利用更多的本机阵列功能:

function destroyer(arr) {
    var removes = Array.prototype.slice.call(arguments, 1);
    return arr.filter(function(item) {
        return removes.indexOf(item) === -1;
    });
}
var result = destroyer([3, 5, 1, 2, 2], 2, 3, 5);
document.write(JSON.stringify(result));

使用ES6套装以提高潜在效率:

    function destroyer(arr) {
        var removes = new Set(Array.prototype.slice.call(arguments, 1));
        return arr.filter(function(item) {
            return !removes.has(item);
        });
    }
    var result = destroyer([3, 5, 1, 2, 2], 2, 3, 5);
    document.write(JSON.stringify(result));

仅供参考,在前面的代码示例中,我尝试过:

var removes = new Set(arguments);

因为它看起来更干净,在IE和Chrome中也很好用,但Firefox中的一个错误使它无法在那里工作。ES6中的arguments应该是一个可迭代的,可以传递给Set构造函数,但Firefox还没有正确实现它。关于这个主题,有一个开放的Firefox bug正在处理中。因此,我放弃了这个代码示例,将其复制到一个真实的数组中,并将数组传递给构造函数。


另一种可能性是使用ES6休息参数:

function destroyer(arr, ...items) {
  var removes = new Set(items);
  return arr.filter(function(item) {
    return !removes.has(item);
  });
}
var result = destroyer([3, 5, 1, 2, 2], 2, 3, 5);
document.write(JSON.stringify(result));

使其(使用indexOfwhile循环)

function destroyer(arr) {
  for(var i = 1; i < arguments.length; i++)
  {
          var index = arr.indexOf( arguments[i] );
          while( index != -1 )
          {
              arr.splice(index, 1);
              console.log(arr);
              index = arr.indexOf( arguments[i] );
          }
  }
  return arr;
}

您需要反复检查它,而不是只检查一次,除非index-1

通过同样的练习,即使指令中规定使用Arguments对象,这个解决方案也能工作:

function destroyer(arr, ...valsToRemove) {
return arr.filter(elem => !valsToRemove.includes(elem));
}