Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering an array with a deeply nested array in JS

How can I filter an array with a deeply nested array? Given the following 2 arrays, I need the result to be an array with only the rice cakes and the gluten-free-pizza objects:

const foodsILike = ['gluten-free', 'carb-free', 'flavor-free'];
const foodsAvailable = [
  { name: 'pasta', tags: ['delicious', 'has carbs']}, 
  { name: 'gluten-free-pizza', tags: ['gluten-free']}, 
  { name: 'pizza', tags: ['delicious', 'best meal of the year']},
  { name: 'rice cakes', tags: ['flavor-free']}
]

I tried the following which just returns everything (the 4 objects):

var result = foodsAvailable.filter(function(food) {
  return foodsILike.filter(function(foodILike) {
    return foodILike === food;
  })
})

result
// Array [ Object, Object, Object, Object]
like image 657
Simpleton Avatar asked Dec 08 '22 17:12

Simpleton


2 Answers

You could use Array#some and Array#includes for checking if foodsILike contains a tag.

const foodsILike = ['gluten-free', 'carb-free', 'flavor-free'];
const foodsAvailable = [{ name: 'pasta', tags: ['delicious', 'has carbs'] }, { name: 'gluten-free-pizza', tags: ['gluten-free'] }, { name: 'pizza', tags: ['delicious', 'best meal of the year'] }, { name: 'rice cakes', tags: ['flavor-free'] }]

var result = foodsAvailable.filter(function(food) {
    return food.tags.some(function(tag) {
        return foodsILike.includes(tag);
    });
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 98
Nina Scholz Avatar answered Dec 10 '22 07:12

Nina Scholz


You are missing a length check on your inner filter and you aren't checking the tags array for the value in that inner filter

const foodsILike = ['gluten-free', 'carb-free', 'flavor-free'];
const foodsAvailable = [
  { name: 'pasta', tags: ['delicious', 'has carbs']}, 
  { name: 'gluten-free-pizza', tags: ['gluten-free']}, 
  { name: 'pizza', tags: ['delicious', 'best meal of the year']},
  { name: 'rice cakes', tags: ['flavor-free']}
]

var result = foodsAvailable.filter(function(food) {
  return foodsILike.filter(function(foodILike) {
    // is value in tags array?
    return food.tags.indexOf(foodILike) >-1;
  }).length;// length acts as boolean, any length greater than zero is truthy
});

console.log(result)
like image 26
charlietfl Avatar answered Dec 10 '22 07:12

charlietfl