Home > other >  How can I filter an array of objects where an array inside the object includes all items from anothe
How can I filter an array of objects where an array inside the object includes all items from anothe

Time:09-23

How can I filter an array of objects, which itself has an array, by a filter by array, where all the items in the filter by array are found in the objects array?

It might be easier to explain with an example:

const data = [
    {user: 'bob', favoriteThings: ['cats', 'dogs', 'movies']},
    {user: 'sally', favoriteThings: ['cats', 'movies', 'trees']},
]

const filterByFavs = ['cats', 'trees']

// result should only include [{user: 'sally', favoriteThings: ['cats', 'movies', 'trees']}]
// if filterByFavs is ['cats'], then both users are returned. 
// favoriteThings has to have all the items from filterByFavs in order for the filter to apply.     

In the above snipped, I am trying to filter the data so that the result only includes objects where all the items in filterByFavs are found in favoriteThings.

I tried to solve this with both reduce and filter and cant seem to get the desired result.

let out = data.filter((fav) => {
    return (
        fav.favoriteThings.filter((tag) => {
            return !filterByFavs.includes(tag);
        })
    );
});

let a = data.reduce((acc, fav) => {
    let favs = fav.favoriteThings;
    let allExists = favs.filter((tag) => !filterByFavs.includes(tag.text));
    if (allExists) {
        acc.push(fav);
        return acc;
    }
    return acc;
}, []);

The issue I am facing in my logic is I can filter fine when filterByFavs only has one item, but not when it has multiple.

CodePudding user response:

Check that .every one of the items to find is included in the other array being iterated over.

const data = [
    {user: 'bob', favoriteThings: ['cats', 'dogs', 'movies']},
    {user: 'sally', favoriteThings: ['cats', 'movies', 'trees']},
];
const filterByFavs = ['cats', 'trees'];
const result = data.filter(
  obj => filterByFavs.every(str => obj.favoriteThings.includes(str))
);
console.log(result);

  • Related