Reputation: 95
I am making a tags feature and based on keywords I want to return one of the custom tags I've associated it with.
For Example:
let title = "The sky is blue today"
let arr = [{
'The sky': ['sky', 'outside'],
'blue': ['bright', 'blue'],
}]
I want to match any strings that could match arr
and return the value. The challenge is also the word "The sky" since I can't just split the string on empty spaces.
Upon retrieving the value, I will do a count on the array of tags and randomly select one (thats the easy part I can do).
Upvotes: 0
Views: 49
Reputation: 46
You can use a combination of the methods Object.keys()
, string.includes()
and Array.reduce()
:
let title = "The sky is blue today"
let tags = {
'The sky': ['sky', 'outside'],
'blue': ['bright', 'blue'],
'house': ['home', 'outside']
}
let matchingTags = Object.keys(tags).reduce((acc, tagKey) => {
return [...acc, ...(title.includes(tagKey) ? tags[tagKey] : [])]
}, [])
console.log(matchingTags) // -> [ 'sky', 'outside', 'bright', 'blue' ]
I removed the array surrounding the tags, please let me know if I missed something here.
Here's what happens:
Object.keys(tags)
creates an array containing the keys of our object tags
: returning an array containing ['The sky', 'blue', 'house']
.
We then iterate on this array using the reduce method. With our array of matching tags as an accumulator.
In the callback of the reduce method, we check if the given title includes the key we're currently looking at. If so, we concatenate the matching tags to the accumulator using destructuring.
EDIT: As pointed out by @georg here, the issue with this method is false positive with words containing the tags. (ex Wired
and red
).
This can be handled by replacing the condition title.includes(tagKey)
with title.includes(tagKey) && !title.split(" ").find(word => word !== tagKey && word.includes(tagKey))
We're here removing the words that do not exactly match the tag key but still contain it.
Upvotes: 3