2

Maybe it's Friday morning and I'm having a moment but cant see why this isn't working.

I have this JSON

var recipes = [{
            name: "Beef Lasagne",
            ingredients: [
                "mince",
                "pasta",
                "sauce",
                "tomatoes"
            ]}]

I can do this: recipes.filter(recipe => recipe.name.includes('e')) and it filters correctly

however when I try and do this: recipes.filter(recipe => recipe.ingredients.includes('e'))

I get I'm trying to filter a string in ex1 and then in ex2 im filter an array, what else do I need to do to get the filter in the second one working?

5
  • You cannot filter an array like that recipe.ingredients.includes('e') - you need to add a filter to that array too or add an ingredient that is just "e" Commented Feb 23, 2018 at 10:41
  • 1
    String.includes() will look for a specific string inside another string. Array.includes() will look for the exact element. So recipe.ingredients.includes('e') only works if the string 'e' is part of the ingredients. Are you trying to search if any of the ingredients has the letter 'e' in it? Commented Feb 23, 2018 at 10:42
  • @Shilly yes exactly Commented Feb 23, 2018 at 10:45
  • @Shilly you should transfer that comment to an answer. Commented Feb 23, 2018 at 10:46
  • 1
    what's your expected output Commented Feb 23, 2018 at 10:46

3 Answers 3

2

Array.includes() will look for a specific element. Since ingredients is an array as well, you need to loop over the ingredients array as well.

So as written, it'll only work if ingredients equals:

    ingredients: [
        "mince",
        "pasta",
        "sauce",
        "tomatoes",
        "e"
    ]

So you probably want something like:

recipes.filter( recipe => recipe.ingredients.some( ingredient => ingredient.includes( 'e' ) ) );

var recipes = [{
    name: "Beef Lasagne",
    ingredients: [
      "mince",
      "pasta",
      "sauce",
      "tomatoes"
    ]
  },
  {
    name: "Beef Lasagne without e",
    ingredients: [
      "minc",
      "past",
      "tomatos"
    ]
  },
  {
    name: "Beef Lasagne with sauce and no mince",
    ingredients: [
      "sauce",
      "pasta",
      "tomatoes"
    ]
  }
]

console.log(
    recipes.filter( recipe => recipe.ingredients.some( ingredient => ingredient.includes( 'e' ) ) )
)
console.log(
    recipes.filter( recipe => recipe.ingredients.some( ingredient => ingredient.startsWith( 'min' ) ) )
)

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

3 Comments

yes this is what I want! this allows me to change the string method, i.e. from includes to startsWith. thanks!
You can use any array method this way to map/filter/reduce specific fields. If you use a library like lodash or underscore, they will have builtin versions of these as well.
sure. i like this method coz it's expandable. and yeh ive used underscore before but try and stay away from librarys when learning :)
0

You could use .join("") on the Array to convert it to a String and be able to use .includes() the way you initially wanted:

var recipes = [
  {
    name: "Beef Lasagne",
    ingredients: [
      "mince",
      "pasta",
      "sauce",
      "tomatoes"
    ]
  },
  {
    name: "Raw Pasta",
    ingredients: [
      "pasta"
    ]
  }
];

recipes = recipes.filter(recipe => recipe.ingredients.join("").includes('e'));

console.log(recipes);

2 Comments

ok yes this works I guess but what if wanted to change my filter so that I could say startsWith() instead. so only return me recipes where the ingredients startWith..
@thewalrus Do you mean the ingredients have to start with 'e'? All of them or some of them?
0

Try this:

recipes.filter(recipe => recipe.ingredients.filter(ingredient => ingredient.includes('e')).length > 0)

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.