从数组中删除所有与特定字符串匹配的元素。

48

如何最方便地从数组中删除所有匹配特定字符串的元素?例如:

array = [1,2,'deleted',4,5,'deleted',6,7];

我想从数组中删除所有的'deleted'

5个回答

89

可以简单地使用 Array.prototype.filter() 方法来获取符合条件的元素。

var array = [1,2,'deleted',4,5,'deleted',6,7];
var newarr = array.filter(function(a){return a !== 'deleted'})

更新:ES6语法

let array = [1,2,'deleted',4,5,'deleted',6,7]
let newarr = array.filter(a => a !== 'deleted')

13
箭头函数语法让它更加简洁明了。 array.filter(a => a !== 'deleted'); 的意思是过滤掉数组中所有值为'deleted'的元素。 - Sterling Archer
如果您想删除包含搜索词部分的元素,您将如何修改此代码?例如,对于以下数组 [1, 2, 'delete', 4, 5, 'deleted', 6, 'will delete'],您该如何操作?如果您想要删除任何与字符串“del”甚至部分匹配的元素,那么“delete”,“deleted”和“will delete”都将被删除,您该怎么做? - user1837608
@user1837608 那时候,你最好使用正则表达式匹配而不是标准匹配,或者匹配字符串的n个元素,但这将是一项昂贵的操作,没有真正的好处。因为它会在需要时混杂着“将删除”,如果需要的话,我可以在下面放置一个答案,但我认为它并不直接符合问题。 - L.P.

11

如果您有多个字符串需要从主数组中移除,您可以尝试这个方法

// Your main array 
var arr = [ '8','abc','b','c'];

// This array contains strings that needs to be removed from main array
var removeStr = [ 'abc' , '8'];

arr = arr.filter(function(val){
  return (removeStr.indexOf(val) == -1 ? true : false)
})

console.log(arr);

// 'arr' Outputs to :
[ 'b', 'c' ]

或者

更好的性能(使用哈希),如果不需要严格类型相等性

// Your main array 
var arr = [ '8','deleted','b','c'];

// This array contains strings that needs to be removed from main array
var removeStr = [ 'deleted' , '8'];
var removeObj = {};  // Use of hash will boost performance for larger arrays
removeStr.forEach( e => removeObj[e] = true);

var res = arr.filter(function(val){
  return !removeObj[val]
})

console.log(res);

// 'arr' Outputs to :
[ 'b', 'c' ]

10

如果您想要相同的数组,可以使用:

var array = [1,2,'deleted',4,5,'deleted',6,7];
var index = "deleted";
for(var i = array.length - 1; i >= 0; i--) {
    if(array[i] === index) {
       array.splice(i, 1);
    }
}

示例1

否则,您可以使用Array.prototype.filter,它将创建一个新数组,并包含所有通过所提供函数实现的测试的元素。

 var arrayVal = [1,2,'deleted',4,5,'deleted',6,7];
function filterVal(value) {
  return value !== 'deleted';
}
var filtered = arrayVal.filter(filterVal);

例子2


我需要保持相同的数组,谢谢。 - Zitoun

6
array = array.filter(function(s) {
    return s !== 'deleted';
});

1
一种规范的答案可能看起来像这样:

[10, 'deleted', 20, 'deleted'].filter(x => x !== 'deleted');
//=> [10, 20]

这里没有什么意外的内容;任何开发人员都可以阅读、理解和维护这段代码。从这个角度来看,这个解决方案很棒。我只是想提供一些不同的观点。
首先,当条件“反转”时,我有时会对过滤器的语义感到困惑:
[2, 3, 2, 3].filter(x => x === 2);
[2, 3, 2, 3].filter(x => x !== 2);

这是一个人为制造的例子,但我敢打赌有些读者会停顿一下。长期以来,这些小的认知障碍可能会让人筋疲力尽。
个人而言,我希望能有一个拒绝方法:
[2, 3, 2, 3].filter(x => x === 2);
[2, 3, 2, 3].reject(x => x === 2);

其次,在这个表达式 x => x === 2 中有很多的“机制”:一个函数表达式,一个参数和一个等式检查。
通过使用柯里化函数,可以将其抽象化处理:
const eq =
  x => y =>
    x === y;

[2, 3, 2, 3].filter(eq(2));
//=> [2, 2]

我们可以看到eq(2)x => x === 2相同,只是更短,并添加了语义。

现在让我们构建一个reject函数并使用eq:
const reject =
  (pred, xs) =>
    xs.filter(x =>
      pred(x) === false);

reject(eq(2), [2, 3, 2, 3]);
//=> [3, 3]

但是如果我们需要拒绝其他东西呢?那么我们可以构建一个使用 eqeither 函数:

const either =
  (...xs) => y =>
    xs.some(eq(y));

reject(either(1, 2), [1, 3, 2, 3]);
//=> [3, 3]

最后回答你的问题:

reject(eq('deleted'), [1, 'deleted', 3]);
//=> [1, 3]

reject(either('deleted', 'removed'), [1, 'deleted', 3, 'removed', 5]);
//=> [1, 3, 5]

我们可以进一步根据不同的谓词进行删除,例如,如果匹配字符串“delete”或为0,则进行删除。

让我们构建一个名为eitherfn的函数,它接受一个谓词列表:

const eitherfn =
  (...fn) => y =>
    fn.some(f =>
      f(y));

现在让我们构建一个match函数:
const match =
  x => y =>
    typeof y === 'string'
      ? y.includes(x)
      : false;

然后:

reject(eitherfn(match('delete'), eq(0)), [0, 1, 'deleted', 3, 'will delete', 5])
// [1, 3, 5]

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