'Effectively Search for set of substrings in a string Javascript
I currently have a string and set of substrings/search strings which I want to effectively search in the given string. This is what I have currently:
const apple = "apple"
const banana = "banana"
const chickoo = "chickoo"
const dates = "dates"
const eggplant = "eggplant"
const default = "default"
let string = "foobar" // This String changes dynamically
if (string.includes(apple)){
return apple;
} else if (string.includes(banana)) {
return banana;
} else if (string.includes(chickoo)) {
return chickoo;
} else if (string.includes(dates)) {
return dates;
} else if (string.includes(eggplant)) {
return eggplant;
} else {
return default;
}
This approach works, however I am looking for a more compact and efficent way of searching for substrings in a given string.
Edit: I am currently using the following way:
const fruits = ["apple", "banana", "chickoo", "dates", "eggplant"];
let string = "foobar" //This is dynamic
for(let fruit in fruits) {
if(string.includes(fruits[fruit])){
return fruits[fruit];
}
}
return "default";
Let me know if there is even more effective way to do this than the above one.
Solution 1:[1]
You can check these includes in one line.
First you have to create the available list and then check it. If it was not found in the list, default is returned.
const apple = "apple"
const banana = "banana"
const chickoo = "chickoo"
const dates = "dates"
const eggplant = "eggplant"
const default = "default"
let string = "foobar" // This String changes dynamically
const availableFruits = [apple, banana, chickoo, dates, egplant]
return availableFruits.includes(string) ? string : default;
Solution 2:[2]
You can use filter()
let string = "foobar" //This is dynamic
var matchingFruits = fruits.filter(fruit=>string.includes(fruit))
return matchingFruit.length>0?matchingFruit[0]:"default"
Solution 3:[3]
Simple case
If you only have a couple of words, you can compose a regular expression - either go with match (see accepted answer), or if you go for simplicity, you can even just reduce the whole string to the word found inside:
found = string.replace(/.*(apple|banana|cherry).*/,"$1")
This will find the last one, btw. Again, string.match() is better, I just don't want to steal @maksymiuk's solution. Regex is faster than multiple straight searches because it only iterates over the string once, looking for all possible candidates.
Now if we're optimizing, let's consider another case:
Look for many words
If there are many search strings (like a whole dictionary) and you only have a relatively short text, a reverse approach could be more efficient. Build a list of words you have, and check them against an object that has the dictionary words as keys.
function searchManyWordsInText(text,wordList) {
let wordLookup = {};
for(let w of wordList) wordLookup[w] = 1;
let textWords = text.split(/\s+/);
for(let x of textWords) if(wordLookup[x]) return x;
return false;
}
// test it:
searchManyWordsInText(
'this is a banana championship',
['apple','banana','cherry']
);
// returns 'banana', the first word found
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jesmoava9 |
| Solution 2 | JaivBhup |
| Solution 3 |
