Reputation: 131
Consider the following array of emojis:
allEmojis = {
"Smileys-People": [
{
"index": 1,
"display": true,
"name": "grinning face",
"shortName": ":grinning:",
"alt": "😀",
"image": "_81",
"position": "0px -80px",
"keywords": [
"face",
"nice",
"smile",
"laugh",
"happy",
"smiling",
"grin",
"teeth",
"cheerful",
"cheery",
"grinning face"
]
},
{
"index": 2,
"display": true,
"name": "smiling face with open mouth",
"shortName": ":smiley:",
"alt": "😃",
"image": "_81",
"position": "-60px -80px",
"keywords": [
"face",
"open mouth",
"awesome",
"yay",
"smile",
"happy",
"smiling",
"grin",
"teeth",
"smiling face with open mouth"
]
}
],
"Animals-Nature": [
{
"index": 3,
"display": true,
"name": "grinning face",
"shortName": ":dog:",
"alt": "🐶",
"image": "_82",
"position": "-60px -20px",
"keywords": [
"animal",
"face",
"pet",
"adorbs",
"dog",
"puppies",
"puppy",
"dog face"
]
},
{
"index": 4,
"display": true,
"name": "smiling face with open mouth",
"shortName": ":cat:",
"alt": "🐱",
"image": "_82",
"position": "-60px -80px",
"keywords": [
"animal",
"face",
"cat",
"kitten",
"kitty",
"pet",
"cat face"
]
}
]
}
And I have the following javascript code to search within the array and set each display
to true
if the keyword
is found, set it to false
if the keyword
is not found. However, some keywords aren't found, even if the value of the input is the same. For example, if I search "smiling" the function works as expected, but if I search "smile" each display
gets set to false
.
emojiTitles = Object.keys(allEmojis).join(",").split(',')
const emojiSeacrh = (e) => {
let value = e.target.value.toUpperCase()
for (let emojiTitle of emojiTitles) {
for (let emoji of allEmojis[emojiTitle]) {
for (let keyword of emoji.keywords) {
if (keyword.toUpperCase().startsWith(value)) {
emoji.display = true
}
else {
emoji.display = false
}
}
}
}
allEmojis = allEmojis
}
I realize my emojiSearch
function isn't the right way to go, but it's the closest I could get after several hours.
I've spent hours trying to find a proper solution to this on SO, but couldn't get something that fits my specific case.
Upvotes: 0
Views: 129
Reputation: 4780
Try this approach 😎
const allEmojis = {"Smileys-People":[{"index":1,"display":true,"name":"grinning face","shortName":":grinning:","alt":"😀","image":"_81","position":"0px -80px","keywords":["face","nice","smile","laugh","happy","smiling","grin","teeth","cheerful","cheery","grinning face"]},{"index":2,"display":true,"name":"smiling face with open mouth","shortName":":smiley:","alt":"😃","image":"_81","position":"-60px -80px","keywords":["face","open mouth","awesome","yay","smile","happy","smiling","grin","teeth","smiling face with open mouth"]}],"Animals-Nature":[{"index":3,"display":true,"name":"grinning face","shortName":":dog:","alt":"🐶","image":"_82","position":"-60px -20px","keywords":["animal","face","pet","adorbs","dog","puppies","puppy","dog face"]},{"index":4,"display":true,"name":"smiling face with open mouth","shortName":":cat:","alt":"🐱","image":"_82","position":"-60px -80px","keywords":["animal","face","cat","kitten","kitty","pet","cat face"]}]};
const keword = 'SMILE';
Object.keys(allEmojis)
.forEach(key => allEmojis[key] = allEmojis[key].map(obj => ({
...obj,
display: obj.keywords.some(tag => tag.toUpperCase().startsWith(keword))
})));
console.log(allEmojis);
.as-console-wrapper{min-height: 100%!important; top: 0}
Upvotes: 1
Reputation: 4464
Your code resets display at each iteration, so the final value is merely the last match on the array.
for (let keyword of emoji.keywords) {
if (keyword.toUpperCase().startsWith(value)) {
emoji.display = true
} else {
emoji.display = false
}
}
You might want to replace all of it with something like
emoji.display = emoji.keywords.some(keyword => keyword.toUpperCase().startsWith(value));
Array.some
returns true if at least one element meets the condition, false if all conditions are false.
Upvotes: 1