简体   繁体   English

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

[英]Remove all elements from array that match specific string

What is the easiest way to remove all elements from array that match specific string?从匹配特定字符串的数组中删除所有元素的最简单方法是什么? For example:例如:

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

I want to remove all 'deleted' from the array.我想从数组中删除所有'deleted'

Simply use the Array.prototype.filter() function for obtain elements of a condition只需使用Array.prototype.filter()函数来获取条件的元素

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

Update: ES6 Syntax更新:ES6 语法

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

If you have multiple strings to remove from main array, You can try this如果你有多个字符串要从主数组中删除,你可以试试这个

// 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' ]

OR或者

Better Performance(Using hash) , If strict type equality not required更好的性能(使用哈希) ,如果不需要严格的类型相等

// 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' ]
array = array.filter(function(s) {
    return s !== 'deleted';
});

If you want the same array then you can use如果你想要相同的数组,那么你可以使用

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);
    }
}

EXAMPLE 1例 1

else you can use Array.prototype.filter which creates a new array with all elements that pass the test implemented by the provided function.否则,您可以使用Array.prototype.filter创建一个新数组,其中包含通过提供的函数实现的测试的所有元素。

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

EXAMPLE 2例2

A canonical answer would probably look like this:规范的答案可能如下所示:

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

There's nothing unexpected here;这里没有什么出乎意料的; any developers can read, understand and maintain this code.任何开发人员都可以阅读、理解和维护此代码。 From that perspective this solution is great.从这个角度来看,这个解决方案很棒。 I just want to offer some different perspectives.我只是想提供一些不同的观点。

Firstly I sometimes struggle with the semantic of filter when the condition is "reversed":首先,当条件“反转”时,我有时会与过滤器的语义作斗争:

[2, 3, 2, 3].filter(x => x === 2);
[2, 3, 2, 3].filter(x => x !== 2);

This is a contrived example but I bet a few readers did pause for a nanosecond.这是一个人为的例子,但我敢打赌,一些读者确实停顿了一纳秒。 These small cognitive bumps can be exhausting in the long run.从长远来看,这些小的认知障碍可能会让人筋疲力尽。

I personally wish there would be a reject method:我个人希望有一个拒绝方法:

[2, 3, 2, 3].filter(x => x === 2);
[2, 3, 2, 3].reject(x => x === 2);

Secondly there's a lot of "machinery" in this expression x => x === 2 : a function expression, a parameter and an equality check.其次,在这个表达式x => x === 2有很多“机器”:一个函数表达式、一个参数和一个相等性检查。

This could be abstracted away by using a curried function:这可以通过使用柯里化函数来抽象出来:

const eq =
  x => y =>
    x === y;

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

We can see that eq(2) is the same as x => x === 2 just shorter and with added semantic.我们可以看到eq(2)x => x === 2相同,只是更短并增加了语义。

Now let's build a reject function and use eq :现在让我们构建一个reject函数并使用eq

const reject =
  (pred, xs) =>
    xs.filter(x =>
      pred(x) === false);

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

But what if we need to reject other things?但是如果我们需要拒绝其他的东西呢? Well we can build an either function that uses eq :嗯,我们可以建立一个either功能,使用eq

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

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

Finally to answer your question:最后回答你的问题:

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

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

We could go further and remove based on different predicates eg remove if matches the string "delete" or is 0 .我们可以更进一步并根据不同的谓词进行删除,例如 remove if 匹配字符串 "delete" 或 is 0

Let's build a eitherfn function that takes a list of predicates:让我们构建一个采用谓词列表的eitherfn函数:

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

And now let's build a match function:现在让我们构建一个match函数:

const match =
  x => y =>
    typeof y === 'string'
      ? y.includes(x)
      : false;

Then:然后:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM