71

How can I check if a string contains any element of an array? I want to filter some array if the element has some string. Please see below code.

var arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
function checker(value) {
 var prohibited = ['banana', 'apple'];
 for (var i = 0; i < prohibited.length; i++) {
 if (value.indexOf(prohibited[i]) == -1) {
 return true;
 } else {
 return false;
 }
 }
}
arr = arr.filter(checker);
console.log(arr);

The result is [ 'apple', 'kiwi', 'orange' ]. The 'apple' should get removed, but it isn't.

Above code only filtered 'banana', not 'apple'. I have many keywords to filter. Is there an easier way?

Tunaki
138k46 gold badges367 silver badges443 bronze badges
asked May 25, 2016 at 5:15
0

8 Answers 8

89

It can be as simple as that:

const arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
const checker = value =>
 !['banana', 'apple'].some(element => value.includes(element));
console.log(arr.filter(checker));

ECMAScript 6 FTW!

The checker uses an arrow function.

The ! means that it will exclude all elements that doesn't meet the conditions.

The some() method tests whether some element in the array passes the test implemented by the provided function.

from Array.prototype.some() docs on MDM

The includes() method determines whether one string may be found within another string, returning true or false as appropriate.

from String.prototype.includes() docs on MDM


As some latest ECMAScript features aren't supported in all browsers, you should use Babel to compile your code to ECMAScript 5.

answered May 25, 2016 at 10:32

1 Comment

How to do this with an array of numbers? am getting "value.includes is not a function" for an array of numbers. Also gives same error for value.indexOf(..) != -1
38

You can use some() function: to check if a string contains any element of an array.

e.g.

var fruitsArr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
var myString = "I have an apple and a watermelon.";
var stringIncludesFruit = fruitsArr.some(fruit => myString.includes(fruit));

This function is pretty new. some() method accepts a callback where you define the condition you want to verify and it returns a boolean. Check the documentation at the link above.

Syscall
19.8k10 gold badges44 silver badges60 bronze badges
answered Apr 7, 2021 at 5:47

1 Comment

This was my favourite of the answers for being well written and easier to read. Thanks.
35

Problem lies in the for loop, which only iterates once since return ends the function, cutting off the for loop in the process. So, you can update the code like so to make the function only return once the for loop has been completed .

var arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
function checker(value) {
 var prohibited = ['banana', 'apple'];
 for (var i = 0; i < prohibited.length; i++) {
 if (value.indexOf(prohibited[i]) > -1) {
 return false;
 }
 }
 return true;
}
arr = arr.filter(checker);
console.log(arr);


For reducing the function you can use every() and indexOf() methods

The 'every' method executes the provided callback function once for each element present in the array until it finds one where callback returns a falsy value (a value that becomes false when converted to a Boolean). If such an element is found, the every method immediately returns false. Otherwise, if callback returned a true value for all elements, every will return true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.(Taken from here )

var arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
function checker(value) {
 var prohibited = ['banana', 'apple'];
 return prohibited.every(function(v) {
 return value.indexOf(v) == -1;
 });
}
arr = arr.filter(checker);
console.log(arr);


For older browser check polyfill option of every method.


You could even use a regex here. Generate regex using the array and use test() to check match

var arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
function checker(value) {
 var prohibited = ['banana', 'apple'];
 var regex = new RegExp(prohibited.map(function(s) {
 return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
 }).join('|'));
 return !regex.test(value);
}
arr = arr.filter(checker);
console.log(arr);

Refer this answer for string to regex conversion : Can you create JavaScript regexes on the fly using string variables?

answered May 25, 2016 at 5:18

Comments

5

For someone looking for simple, single-liner:

arr.filter(item => !prohibited.some(prohb => item.includes(prohb))) // ["kiwi", "orange"]
answered Feb 13, 2020 at 17:47

Comments

4

I think this can be greatly simplified. There is already a built in within javascript for checking these things. Consider:

var arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
function checker(value) {
 var prohibited = ['banana', 'apple'];
 // indexOf() returns -1 if the element doesn't exist in the prohibited array
 return prohibited.indexOf( value ) == -1;
}
arr = arr.filter(checker);
console.log(arr);
answered May 25, 2016 at 13:51

1 Comment

Unfortunately, this approad doesn't work the same way as the original. Please note that in the original, the comparison is made with String.prototype.indexOf(), but this uses Array.prototype.indexOf(). In essence, in the original, for the second element of arr, the monkey banana, it calls 'monkey banana'.indexOf('banana'), which returns 7 (and then a second call for the second element of prohibited). In your example, it calls ['banana', 'apple'].indexOf('monkey banana'), which returns -1.
4

Some may argue that this is a questionable practice, but you may find it useful to have a method that you can run on the string directly - in which case you could extend the JavaScript String object using String.prototype.

Like this...

String.prototype.containsAny = String.prototype.containsAny || function(arr) {
 for (var i = 0; i < arr.length; i++) {
 if (this.indexOf(arr[i]) > -1) {
 return true;
 }
 }
 return false;
};

As you can see in this example, it will default to any existing definition of a containsAny method. Keep in mind: any time you're augmenting built-in objects, it's a good idea to at least check for the presence of the property first – perhaps some day it will exist... ̄\_(ツ)_/ ̄

Check out this fiddle for usage or see below:

var str = 'This is a sentence as a string.';
console.log(str.containsAny(['string1', 'string2', 'string3'])); // -> returns false
console.log(str.containsAny(['string', 'string1', 'string2'])); // -> returns true
<script src="//cdn.simpledigital.net/common/js/extensions/String.prototypeHelpers.js"></script>

answered Jul 18, 2018 at 18:18

Comments

3
 const stringInput = "I have a kiwi";
 const arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
 const exists = arr.some((t) => stringInput.indexOf(t) > -1); 
or
 const exists = arr.some((t) => stringInput.includes(t)); 
// iterate through arr items.
// If any of your item is a substring in the input string, then the result of the statement will be `true` otherwise will be `false`.

For some function please check this reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

For includes function please check this reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes

answered Jan 11, 2022 at 14:03

1 Comment

While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please include an explanation for your code, as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
0

For example by building a RegExp and testing against that:

var arr = ['banana', 'monkey banana', 'apple', 'kiwi', 'orange'];
var prohibited = ['banana', 'apple'];
var escapeForRegex = function(str) {
 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\1ドル');
};
var r = new RegExp(prohibited.map(escapeForRegex).join("|"));
arr.filter(function(v){ return !r.test(v) });
answered May 25, 2016 at 5:37

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.