227

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?

Dane Brouwer
  • 2,827
  • 1
  • 22
  • 30
user6234002
  • 2,415
  • 2
  • 10
  • 5

18 Answers18

386

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.

// test cases
const str1 = 'hi hello, how do you do?';
const str2 = 'regular string';
const str3 = 'hello there';

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

// run the tests against every element in the array
const test1 = conditions.some(el => str1.includes(el));
const test2 = conditions.some(el => str2.includes(el));
// strictly check that contains 1 and only one match
const test3 = conditions.reduce((a,c) => a + str3.includes(c), 0) == 1;

// display results
console.log(`Loose matching, 2 matches "${str1}" => ${test1}`);
console.log(`Loose matching, 0 matches "${str2}" => ${test2}`);
console.log(`Exact matching, 1 matches "${str3}" => ${test3}`);

Also, as a user mentions below, it is also interesting to match "exactly one" appearance like mentioned above (and requested by OP). This can be done similarly counting the intersections with .reduce and checking later that they're equal to 1.

dinigo
  • 6,872
  • 4
  • 37
  • 48
  • 4
    Point of note: `some()` is a method, not an operator. Otherwise, good answer. – Mitya Jan 07 '18 at 18:01
  • 1
    Just to to highlight for anyone more distracted, the fact that, as is correctly bolded in the answer, this is good for when 'at least one element' is in the array but unfortunately it doesn't answer the question of the OP: 'only one of the conditions is true.' – user3658510 Aug 20 '21 at 01:29
  • 1
    You are right. Added extra condition to demonstrate how to reduce the array to check How many matches – dinigo Aug 20 '21 at 10:18
71

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 = ['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
Mitya
  • 33,629
  • 9
  • 60
  • 107
  • This will not work if the words contain special regexp characters. Also, this won't satisfy the OP's apparent requirement it match only if there's a match with a **single** word. –  Jun 18 '16 at 13:38
  • Hey, Mitya, I wrote this popular answer but I happen to like more your solution. I've tryed a number of times to restrict the results to *only one* but can't bend regex to do it. `(hello|hi|howdy){1}` is not working. Any idea? – dinigo Nov 08 '21 at 17:33
  • 1
    How do you mean exactly? If you want to match only one, not multiple, then surely the original `includes()` is what you need. – Mitya Nov 09 '21 at 10:47
  • I can't seem to find a way to match "one and only one" of the purposed words with a single regex. Maybe you can 1st match and then count whether the num results == 1. Not sure – dinigo Nov 09 '21 at 14:17
  • 1
    REGEX isn't the tool for stipulating how many of a whitelisted pool of options are found (or not). It deals with sequences, so you might struggle here. – Mitya Nov 09 '21 at 16:19
42

You could also do something like this :

const str = "hi, there"

const res = str.includes("hello") || str.includes("hi") || str.includes('howdy');

console.log(res);

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

Dženis H.
  • 7,284
  • 3
  • 25
  • 44
Thomas Leclerc
  • 429
  • 4
  • 2
38

That should work even if one, and only one of the conditions is true :

var str = "bonjour le monde vive le javascript";
var arr = ['bonjour','europe', 'c++'];

function contains(target, pattern){
    var value = 0;
    pattern.forEach(function(word){
      value = value + target.includes(word);
    });
    return (value === 1)
}

console.log(contains(str, arr));
kevin ternet
  • 4,514
  • 2
  • 19
  • 27
  • 1
    Just a note. Anyone trying this in Google Apps Script will get a TypeError: https://stackoverflow.com/questions/51291776/typeerror-cannot-find-function-includes-in-object-even-though-the-object-is-an – Kurt Leadley Aug 14 '19 at 16:50
  • 1
    Use the indexOf('string') !== -1 instead of the includes to avoid this error – Raphaël Balet Jan 27 '21 at 10:43
  • @Raphaël I'm sorry, I don't understand how to use your mentioned method. Could you provide a more elaborate code snippet? – andylib93 Feb 26 '22 at 12:13
  • `value = value + (+!!target.includes(word));` fixed my problem. I found an answer [here](https://stackoverflow.com/a/59694631/11160383) – andylib93 Feb 26 '22 at 12:30
8

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
Denys Rusov
  • 560
  • 6
  • 6
4

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 returns a filtered array (which I find easier 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"]
SherylHohman
  • 16,580
  • 17
  • 88
  • 94
Romingo
  • 41
  • 5
4

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
James Broad
  • 1,210
  • 12
  • 17
1

Another one!

let result

const givenStr = 'A, X' //values separated by comma or space.

const allowed  = ['A', 'B']
const given    = givenStr.split(/[\s,]+/).filter(v => v)

console.log('given (array):', given)

// given contains none or only allowed values:

result = given.reduce((acc, val) => {
  return acc && allowed.includes(val)
}, true)

console.log('given contains none or only allowed values:', result)

// given contains at least one allowed value:

result = given.reduce((acc, val) => {
  return acc || allowed.includes(val)
}, false)

console.log('given contains at least one allowed value:', result)
lsblsb
  • 1,292
  • 12
  • 19
1

Exact matching with array data/

const dataArray = ["amoos", "rifat", "hello"];

const findId = ( data, id ) => {
  let res = data.find(el => el === id )
  return res ? true : false;
}

console.log( findId( dataArray, 'Hi') ) // false
console.log( findId( dataArray, 'amoos') ) // true
GMKHussain
  • 3,342
  • 1
  • 21
  • 19
1

it depends what context you're using it in. I used it on an object to check if any of the keys had an empty string or null as its value and it worked

Object.values(object).includes('' || null)
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 26 '22 at 07:06
0

1 Line solution:

String/Array.prototype.includes('hello' || 'hi' || 'howdy');

let words = 'cucumber, mercy, introduction, shot, howdy'
words.includes('hi' || 'howdy' || 'hello') // true
words.includes('hi' || 'hello') // false
Dimitar Cetelev
  • 364
  • 1
  • 9
  • 2
    Because `'hi'` is not `undefined` or `false`, the code sample you have provided is checking if the `words` string includes `hi` therefore both `words.includes(...)` statements return false. – Tyler2P Aug 23 '21 at 18:27
0

const givenArray = ['Hi , how are you', 'how are you', 'howdy, how you doing']
const includeValues = ["hello", "hi", "howdy"]
const filteredStrArray = givenArray.filter(str => includeValues.some(value => str.toLowerCase().includes(value)))

console.log(filteredStrArray);
Md Ishaq
  • 21
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 22 '22 at 20:47
0

Def an old thread but still getting newer replies. I didn't see it on the results and it's one of the easiest ways to use .includes to search for multiple things in a string at once. Depending on what you are trying to do with it just run a for loop that runs through an array of items you want to check a string for using .includes.

Const text = ' does this include item3? ';

For(i = 0; i < arr.length; i++)
{if (text.includes(arr[i])){/* do whatever */ } }

It will return true if any of those items are in that string and then you can have it do whatever.. execute a function, change a variable etc... You can also add what to do if it's false in the if statement as well.

It's worth noting though that it will execute that code for each item that is in the list that returns true so make sure you compensate for that in the code you want executed.

Edit- you could also convert this to a function set it up to pass arguments that are the multiple things you check to see if the string includes and just have it return true or false and you can do whatever with that information outside of the function.

0
string.match( /apple|banana/ ) // <-- Use Regex
t33n
  • 171
  • 1
  • 10
0

maybe late but here is my solution for an array and two or more items /one|two/.test(['one', 'two', 'three', 'four'].join(' '))

console.log(/one|two/.test(['one', 'two', 'three', 'four'].join(' ')))
Ruslan Semenov
  • 319
  • 3
  • 5
-1

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
iProDev
  • 547
  • 6
  • 5
-3

You can do this

["hello", "hi", "howdy"].includes(str)
  • Unfortunately this will search whether the whole `str` is contained inside `hello`, `hi` or `howdy`. – I give you an upvote back, as I hate downvotes to honest efforts, without comments to explain what was wrong. Anyway I suggest you to delete the answer to not get further downvotes. – Kamafeather Aug 23 '22 at 21:03
  • as @Kamafeather mentioned, this doesn't work – Eyal Solomon Mar 01 '23 at 08:44
-5

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

neatsu
  • 162
  • 2
  • 6
  • 2
    No, it doesn't work: `['hello', 'hi', 'howdy'].includes('hello, how are you ?')` returns `false`, whereas OP is asking for a solution that returns `true`. – Basj Sep 07 '20 at 11:24