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);