multiple conditions for JavaScript .includes() method
JavascriptMethodsJavascript Problem Overview
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?
Javascript Solutions
Solution 1 - Javascript
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.
Solution 2 - Javascript
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
Solution 3 - Javascript
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));
Solution 4 - Javascript
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.
Solution 5 - Javascript
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
Solution 6 - Javascript
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"]
Solution 7 - Javascript
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
Solution 8 - Javascript
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)
Solution 9 - Javascript
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);
Solution 10 - Javascript
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
Solution 11 - Javascript
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
Solution 12 - Javascript
How about ['hello', 'hi', 'howdy'].includes(str)
?