1

I have an array of object and need to check if the any value of a second array is included within a specific field.

My array is called cocktailList and the field I need to check against is called "ingredients".

The second array is called selectedOptions.

The following code works perfectly when the second array has only 1 value.

Example

const selectedOptions = ["vodka"];
const selectedDrinks = cocktailList.filter(function (item, i) {
      if (item.ingredients.toLowerCase().includes(selectedOptions)) {
        return true;
      } else false;
    });

The problem occurs when I have more than 1 value in selectedOptions My objective is to return TRUE if the item.ingredients contains ANY value of selectedOptions.

If I have the following:

const selectedOptions = ["vodka", "rum"];

It would only return true if the ingredients field contains all values of selectedOptions

I've tried the following solution as suggested by others

if (item.ingredients.toLowerCase().some((val) => selectedOptions.indexOf(val) !== -1))

but I'm getting an error

TypeError: item.ingredients.toLowerCase().some is not a function. (In 'item.ingredients.toLowerCase().some(function (i)

Each item is an object which contains "ingredients" field containing a string of this kind

 Object {
    "alcoholic": "true",
    "complete": false,
    "country": "cuba",
    "dairy_free": "",
    "description": "Made without the traditional orange liqueur",
    "difficulty": "",
    "dosage": "1½ shot(s) Tequila, ½ shot(s) Lime Juice, ½ shot(s)",
    "drinkId": "1103",
    "equipment": "Shaker, Strainer",
    "garnish": "",
    "glass": "collins",
    "ingredients": "Tequila, Lime Juice, Agave Nectar Juice",
}
7
  • Seems like the question is in JavaScript - please tag question. Commented Sep 21, 2020 at 13:50
  • Please show us the value of cocktailList. It looks like in the original code, the item.ingredients is a string but in the other example it is not? Commented Sep 21, 2020 at 15:12
  • @Bergi I've updated my question and included an object example at the bottom. The ingredient field is indeed a string. Commented Sep 21, 2020 at 15:40
  • Ah. You'll want to use selectedOptions.some(…) then, not ingredients.….some(…). Commented Sep 21, 2020 at 16:09
  • @Bergi like this you mean const selectedDrinks = cocktailList.filter(function (item, i) { if (selectedOptions.some(item.ingredients.toLowerCase())) { return true; } else false; }); Commented Sep 21, 2020 at 16:14

3 Answers 3

1

You can use some.

Borrowing snippet from @ikik:

let cocktailListc = [{
    "ingredients": "vodka"
  },
  {
    "ingredients": "water"
  },
  {
    "ingredients": "soda"
  },
  {
    "ingredients": "rum"
  },
  {
    "ingredients": "orange"
  }
]
const selectedOptions = ["vodka", "rum", "limun"];

console.log(cocktailListc.some(item => selectedOptions.includes(item.ingredients)))

But will fail when

let cocktailListc = [{
    "ingredients": "vodka"
  },
  {
    "ingredients": "water"
  },
  {
    "ingredients": "soda"
  },
  {
    "ingredients": "rum"
  },
  {
    "ingredients": "orange"
  }
]
const selectedOptions = ["a", "b", "c"];

console.log(cocktailListc.some(item => selectedOptions.includes(item.ingredients)))

Sign up to request clarification or add additional context in comments.

Comments

0

You can do simple double loop...

function test() {
  let cocktailListc = [{
      "ingredients": "Tequila, Lime Juice, Agave Nectar Juice, Russian Vodka"
    },
    {
      "ingredients": "water test"
    },
    {
      "ingredients": "soda test"
    },
    {
      "ingredients": "rum test"
    },
    {
      "ingredients": "orange test"
    }
  ]

  const selectedOptions = ["vodka", "rum", "limun"];

  let check = [];

  selectedOptions.forEach(opt => {
    cocktailListc.forEach(cocktail => {
      if (cocktail.ingredients.toLowerCase().includes(opt.toLowerCase()) === true) {
        check.push(cocktail);
      }
    });
  });

  if (check.length > 0) {
    console.log(true)
     console.log(check)
  }
}
test()

4 Comments

you are assuming that the values of selectedOptions must be equal to the value of ingredients which is not the case at all. Example "ingredients": "Tequila, Lime Juice, Agave Nectar Juice, Russian Vodka" and selectedOptions = ["vodka", "rum", "whiskey"]
@Butri I just changed that min ago after seeing your edit, easy fix: if (cocktail.ingredients.includes(opt) === true) {
I think we're on the right path however your solution is not returning what I need. If you check my code I'm adding the cocktail object every time there's a match therefore I don't think we should use check.push(opt). Just to clarify, I need to end up with let check = []; containing all objects where the field ingredients contains one of the selectedOptions values.
@Butri Oh I see, but then just switch it and push check.push(cocktail);, cocktail object and not a opt (an option). Edited fiddle.
0

You could do:

var selectedOptions = ["vodka"];
var cocktailList = [{ ingredients: "vodka, lemon, sugar" }];

var selectedDrinks = cocktailList.filter((cocktail, i) =>
  selectedOptions.reduce(
    (has, option) => has && cocktail.ingredients.includes(option),
    true
  )
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.