DogFoxX
DogFoxX

Reputation: 131

Search Nested Array within Array Object for Value

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

Answers (2)

A1exandr Belan
A1exandr Belan

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

Balastrong
Balastrong

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

Related Questions