[javascript] multiple conditions for JavaScript .includes() method

Just wondering, is there a way to add multiple conditions to a .includes method, for example:

    var value = str.includes("hello", "hi", "howdy");

Imagine the comma states "or".

It's asking now if the string contains hello, hi or howdy. So only if one, and only one of the conditions is true.

Is there a method of doing that?

This question is related to javascript methods

The answer is


Here's a controversial option:

String.prototype.includesOneOf = function(arrayOfStrings) {
  if(!Array.isArray(arrayOfStrings)) {
    throw new Error('includesOneOf only accepts an array')
  }
  return arrayOfStrings.some(str => this.includes(str))
}

Allowing you to do things like:

'Hi, hope you like this option'.toLowerCase().includesOneOf(["hello", "hi", "howdy"]) // True

How about ['hello', 'hi', 'howdy'].includes(str)?


You could also do something like this :

_x000D_
_x000D_
const str = "hi, there"_x000D_
_x000D_
const res = str.includes("hello") || str.includes("hi") || str.includes('howdy');_x000D_
_x000D_
console.log(res);
_x000D_
_x000D_
_x000D_

Whenever one of your includes return true, value will be true, otherwise, it's going to be false. This works perfectly fine with ES6.


Another one!

_x000D_
_x000D_
let result_x000D_
_x000D_
const givenStr = 'A, X' //values separated by comma or space._x000D_
_x000D_
const allowed  = ['A', 'B']_x000D_
const given    = givenStr.split(/[\s,]+/).filter(v => v)_x000D_
_x000D_
console.log('given (array):', given)_x000D_
_x000D_
// given contains none or only allowed values:_x000D_
_x000D_
result = given.reduce((acc, val) => {_x000D_
  return acc && allowed.includes(val)_x000D_
}, true)_x000D_
_x000D_
console.log('given contains none or only allowed values:', result)_x000D_
_x000D_
// given contains at least one allowed value:_x000D_
_x000D_
result = given.reduce((acc, val) => {_x000D_
  return acc || allowed.includes(val)_x000D_
}, false)_x000D_
_x000D_
console.log('given contains at least one allowed value:', result)
_x000D_
_x000D_
_x000D_


You can use the .some method referenced here.

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

_x000D_
_x000D_
// test cases
var str1 = 'hi, how do you do?';
var str2 = 'regular string';

// do the test strings contain these terms?
var conditions = ["hello", "hi", "howdy"];

// run the tests against every element in the array
var test1 = conditions.some(el => str1.includes(el));
var test2 = conditions.some(el => str2.includes(el));

// display results
console.log(str1, ' ===> ', test1);
console.log(str2, ' ===> ', test2);
_x000D_
_x000D_
_x000D_


Not the best answer and not the cleanest, but I think it's more permissive. Like if you want to use the same filters for all of your checks. Actually .filter() works with an array and return a filtered array (wich I find more easy to use too).

var str1 = 'hi, how do you do?';
var str2 = 'regular string';
var conditions = ["hello", "hi", "howdy"];

// Solve the problem
var res1 = [str1].filter(data => data.includes(conditions[0]) || data.includes(conditions[1]) || data.includes(conditions[2]));
var res2 = [str2].filter(data => data.includes(conditions[0]) || data.includes(conditions[1]) || data.includes(conditions[2]));

console.log(res1); // ["hi, how do you do?"]
console.log(res2); // []


// More useful in this case
var text = [str1, str2, "hello world"];

// Apply some filters on data
var res3 = text.filter(data => data.includes(conditions[0]) && data.includes(conditions[2]));
// You may use again the same filters for a different check
var res4 = text.filter(data => data.includes(conditions[0]) || data.includes(conditions[1]));

console.log(res3); // []
console.log(res4); // ["hi, how do you do?", "hello world"]

Extending String native prototype:

if (!String.prototype.contains) {
    Object.defineProperty(String.prototype, 'contains', {
        value(patterns) {
            if (!Array.isArray(patterns)) {
                return false;
            }

            let value = 0;
            for (let i = 0; i < patterns.length; i++) {
                const pattern = patterns[i];
                value = value + this.includes(pattern);
            }
            return (value === 1);
        }
    });
}

Allowing you to do things like:

console.log('Hi, hope you like this option'.toLowerCase().contains(["hello", "hi", "howdy"])); // True

With includes(), no, but you can achieve the same thing with REGEX via test():

var value = /hello|hi|howdy/.test(str);

Or, if the words are coming from a dynamic source:

var words = array('hello', 'hi', 'howdy');
var value = new RegExp(words.join('|')).test(str);

The REGEX approach is a better idea because it allows you to match the words as actual words, not substrings of other words. You just need the word boundary marker \b, so:

var str = 'hilly';
var value = str.includes('hi'); //true, even though the word 'hi' isn't found
var value = /\bhi\b/.test(str); //false - 'hi' appears but not as its own word

That can be done by using some/every methods of Array and RegEx.

To check whether ALL of words from list(array) are present in the string:

const multiSearchAnd = (text, searchWords) => (
  searchWords.every((el) => {
    return text.match(new RegExp(el,"i"))
  })
)

multiSearchAnd("Chelsey Dietrich Engineer 2018-12-11 Hire", ["cle", "hire"]) //returns false
multiSearchAnd("Chelsey Dietrich Engineer 2018-12-11 Hire", ["che", "hire"]) //returns true

To check whether ANY of words from list(array) are present in the string:

const multiSearchOr = (text, searchWords) => (
  searchWords.some((el) => {
    return text.match(new RegExp(el,"i"))
  })
)

multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["che", "hire"]) //returns true
multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["aaa", "hire"]) //returns true
multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["che", "zzzz"]) //returns true
multiSearchOr("Chelsey Dietrich Engineer 2018-12-11 Hire", ["aaa", "1111"]) //returns false