Hadi Pawar
Hadi Pawar

Reputation: 1126

Filter an array of objects using multiple values from the object

So I have an array of objects that looks like this :

let medicines = [
 {
   id:3340,
   name:nutraplus,
   description:"some medicine",
   ingredients: [{
         ingredient:"glycerol"
         },
         {
          ingredient:"Morphine"
         }
        ]
  },
   {
   id:3320,
   name:Panadol,
   description:"tablet",
   ingredients: [{
         ingredient:"Paracetamol"
         },
         {
          ingredient:"Some stuff"
         }
        ]
  }
]

I want to to be able to filter by name and by ingredient name I have acheived the former by doing this :

computed: {
    medicines() {
        return this.$store.state.medicines.filter(med => {
            //this.search is the what comes after typing in search bar
            return med.name.toLowerCase().includes(this.search.toLowerCase())
        })
    },
}

Its vue.js so the computed() stuff anyways this works perfectly when searching by name however i also want to be able to search by ingredients from the same search bar. I tried something like this :

edicines() {
    return this.$store.state.medicines.filter(med => {
        return med.name.toLowerCase().includes(this.search.toLowerCase()) || med.ingredients.map(ing=>{
            ing.ingredient.name.toLowerCase().includes(this.search.toLower)
        })
    })
}

But it didn't work. Any ideas on how to get this working? Thank you for your time.

Upvotes: 1

Views: 101

Answers (2)

Rush W.
Rush W.

Reputation: 1361

Haven't used vue in the example, you just need to extract the logic behind the filtering that I have done (Simple JS filtering)

As example -

Try searching for 'Para' - It must return the entries with name/ingredient containing Para

Try searching for 'stuff' - It should return two entries (since both medicine in that array consist of 'some stuff' as ingredient)

let medicines = [{
    id: 3340,
    name: 'nutraplus',
    description: "some medicine",
    ingredients: [{
        ingredient: "glycerol"
      },
      {
        ingredient: "Morphine"
      },
      {
        ingredient: "Some stuff"
      }
    ]
  },
  {
    id: 3320,
    name: 'Panadol',
    description: "tablet",
    ingredients: [{
        ingredient: "Paracetamol"
      },
      {
        ingredient: "Some stuff"
      }
    ]
  },
  {
    id: 3311,
    name: 'Amazin',
    description: "tablet"
  }
];

const form = document.querySelector('form')
form.addEventListener('submit', (e) => {
  e.preventDefault();
  const searchValue = form.searchText.value.toLowerCase();
  const matchValue = medicines.filter(medicine => {

    return medicine.name.toLowerCase().includes(searchValue) || (medicine.ingredients ? medicine.ingredients.filter(ingredientObj => {
      return ingredientObj.ingredient.toLowerCase().includes(searchValue);
    }).length > 0 : false);
  });

  document.querySelector('.result').textContent = JSON.stringify(matchValue, null, 4);
});
pre {
  background: #c5c5c5;
}
<form>
  <label for="searchText"></label>
  <input type="text" id="searchText" name="searchText">
  <button>Search</button>
</form>
<pre class='result'></pre>

Upvotes: 1

Sebastian Wrzalek
Sebastian Wrzalek

Reputation: 131

This should work.

let medicines = [
 {
   id:3340,
   name:"nutraplus",
   description:"some medicine",
   ingredients: [{
         ingredient:"glycerol"
         },
         {
          ingredient:"Morphine"
         }
        ]
  },
   {
   id:3320,
   name:"Panadol",
   description:"tablet",
   ingredients: [{
         ingredient:"Paracetamol"
         },
         {
          ingredient:"Some stuff"
         }
        ]
  }
];

const searchPhrase = "Paracetamol";

const filteredByName = medicines.filter((medicine) => {
    return medicine.name.toLowerCase() === searchPhrase.toLowerCase();
});

const filteredByIngredient = medicines.filter((medicine) => {
    return medicine.ingredients.some((item) => item.ingredient.toLowerCase() === searchPhrase.toLowerCase());
})

const result = [...filteredByName, ...filteredByIngredient];
console.log(result)

Upvotes: 1

Related Questions