在Javascript/jQuery中从数组中删除多个元素

175

我有两个数组。第一个数组包含一些值,而第二个数组包含应从第一个数组中删除的值的索引。例如:

var valuesArr = new Array("v1","v2","v3","v4","v5");   
var removeValFromIndex = new Array(0,2,4);

我想从valuesArr中删除索引为0,2,4的值。 我认为使用内置的splice方法可能有所帮助,所以我想到了以下方法:

$.each(removeValFromIndex,function(index,value){
    valuesArr.splice(value,1);
});

但这并没有起作用,因为在每次splice之后,valuesArr中的值的索引都会改变。我可以通过使用临时数组并将所有值复制到第二个数组来解决这个问题,但我想知道是否有任何本地方法可以传递多个索引以从数组中删除值。

我更喜欢使用jQuery解决方案。(不确定是否可以在这里使用grep

27个回答

5

ES6快速一行代码:

const valuesArr = new Array("v1","v2","v3","v4","v5");   
const removeValFromIndex = new Array(0,2,4);

const arrayWithValuesRemoved = valuesArr.filter((value, i) => removeValFromIndex.includes(i))

如果您将removeValFromIndex更改为Set()并使用removeValFromIndex.has而不是includes,则代码运行速度应该更快。 - user3064538

5

一种使用ES5的简单解决方案。如今,许多人不再想依赖jQuery等工具,因此这似乎更适合大多数应用程序。

当要删除的索引按升序排序时:

var valuesArr = ["v1", "v2", "v3", "v4", "v5"];   
var removeValFromIndex = [0, 2, 4]; // ascending

removeValFromIndex.reverse().forEach(function(index) {
  valuesArr.splice(index, 1);
});

当要删除的索引未排序时:

var valuesArr = ["v1", "v2", "v3", "v4", "v5"];   
var removeValFromIndex = [2, 4, 0];  // unsorted

removeValFromIndex.sort(function(a, b) { return b - a; }).forEach(function(index) {
  valuesArr.splice(index, 1);
});

2
如果您正在使用 underscore.js,您可以使用 _.filter() 来解决您的问题。
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
var filteredArr = _.filter(valuesArr, function(item, index){
                  return !_.contains(removeValFromIndex, index);
                });

此外,如果您想使用项目列表而不是索引来删除项目,则可以简单地使用_.without(),如下所示:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var filteredArr = _.without(valuesArr, "V1", "V3");

现在filteredArr应该是["V2", "V4", "V5"]

underscore中如何实现contains函数...如果它在filter内部等同于indexOf,请小心...这样做并不是最优的选择... - Alvaro Silvino

1
这是一个快速的例子。
function removeFromArray(arr, toRemove){
    return arr.filter(item => toRemove.indexOf(item) === -1)
}

const arr1 = [1, 2, 3, 4, 5, 6, 7]
const arr2 = removeFromArray(arr1, [2, 4, 6]) // [1,3,5,7]

filter 内部的 indexOf 不是最优解。 - Alvaro Silvino

1

filter + indexOf (IE9+):

这句话涉及编程相关内容,保留了HTML标签,不做解释。
function removeMany(array, indexes) {
  return array.filter(function(_, idx) {
    return indexes.indexOf(idx) === -1;
  });
}); 

或者使用ES6 filter + find(Edge+):

function removeMany(array, indexes = []) {
  return array.filter((_, idx) => indexes.indexOf(idx) === -1)
}

filter 内部的 indexOf 不是最优解。 - Alvaro Silvino

1

1

试试这个

var valuesArr = new Array("v1", "v2", "v3", "v4", "v5");
console.info("Before valuesArr = " + valuesArr);
var removeValFromIndex = new Array(0, 2, 4);
valuesArr = valuesArr.filter((val, index) => {
  return !removeValFromIndex.includes(index);
})
console.info("After valuesArr = " + valuesArr);


1

您可以通过将removeValFromIndex替换为removeValFromIndex.reverse()来纠正您的代码。如果该数组不能保证使用升序,则可以改用removeValFromIndex.sort(function(a, b) { return b - a })


看起来不错 - http://jsfiddle.net/mrtsherman/gDcFu/2/。尽管这假设移除列表是有序的。 - mrtsherman
@minopret:谢谢,但只有在removeValFromIndex中的索引按升序排列时才有效。 - Ajinkya

0
var valuesArr = new Array("v1","v2","v3","v4","v5");   
var removeValFromIndex = new Array(0,2,4);

console.log(valuesArr)
let arr2 = [];

for (let i = 0; i < valuesArr.length; i++){
  if (    //could also just imput this below instead of index value
    valuesArr[i] !== valuesArr[0] && // "v1" <--
    valuesArr[i] !== valuesArr[2] && // "v3" <--
    valuesArr[i] !== valuesArr[4]    // "v5" <--
  ){
    arr2.push(valuesArr[i]);
  }
}

console.log(arr2);

这个方法是可行的。但是在这个过程中,你会创建一个新的数组。不确定这是否符合你的要求,但从技术上讲,它将是一个仅包含你想要的值的数组。


0
听起来 应用 可能是你正在寻找的。
也许像这样的东西可以工作?

Array.prototype.splice.apply(valuesArray, removeValFromIndexes );

但是 .splice() 方法不需要一个要删除的元素列表,它需要一个要开始删除的元素的单个索引,后跟要删除的元素数量... - nnnnnn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接