I have a problem implementing filtering for nested data. I have this kind of data from API :
const animals = {
bugs: ['ant', 'cricket'],
fish: ['shark', 'whale', 'tuna'],
mammals: ['cow', 'horse', 'sheep'],
birds: ['eagle', 'crow', 'parrot'],
predators: ['tiger', 'lion']
}
I have to filter them with this array :
const data = ['shark', 'horse', 'cow', 'parrot']
The result I want to achieve :
const filtered = {
fish: ['shark'],
mammals: ['cow', 'horse'],
birds: ['parrot'],
}
I have tried :
filter.forEach((item) => {
for (let key in animals) {
let species = []
if (animals[key].includes(item)) {
filtered[key] = [...species, species]
}
}
})
and the result :
const filtered = {
fish: ['whale'],
mammals: ['cow',],
birds: ['parrot'],
}
I still can't achieve the desired outcome, because the items inside array will not be added but replaced. I'm stuck here. Any help will be really appreciated. Thanks !
CodePudding user response:
You could rebuild the entries of the object.
const
animals = { bugs: ['ant', 'cricket'], fish: ['shark', 'whale', 'tuna'], mammals: ['cow', 'horse', 'sheep'], birds: ['eagle', 'crow', 'parrot'], predators: ['tiger', 'lion'] },
data = ['shark', 'horse', 'cow', 'parrot'],
result = Object.fromEntries(Object
.entries(animals)
.flatMap(([k, a]) => {
a = a.filter(v => data.includes(v));
return a.length
? [[k, a]]
: []
})
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
First you need to loop your object then filter arrays of animals according to data.
const animals = { fish: ['shark', 'whale', 'tuna'], mammals: ['cow', 'horse', 'sheep'], birds: ['eagle', 'crow', 'parrot'],};
const data = ['shark', 'horse', 'cow', 'parrot'];
let filtered = {};
for (var a of Object.keys(animals)) {
filtered[a] = animals[a].filter(value => data.includes(value));
}
console.log(filtered);
CodePudding user response:
You can use the filter
method:
const fish = animals.fish.filter((animal) => animal === 'shark');
const mammals = animals.mammals.filter((animal) => animal === 'cow' || animal === 'horse');
const birds = animals.birds.filter((animal) => animal === 'parrot');
const filtered = {
fish, // equals to fish: fish
mammals, // equals to mammals: mammals
birds, // equals to birds: birds
};
Note that this is just an example. You can put your own checks in the callback functions but it should return a boolean.
CodePudding user response:
You can iterate over the object and create a new one with the filtered data
const animals = {
bugs: ['ant', 'cricket'],
fish: ['shark', 'whale', 'tuna'],
mammals: ['cow', 'horse', 'sheep'],
birds: ['eagle', 'crow', 'parrot'],
predators: ['tiger', 'lion']
}
const data = ['shark', 'horse', 'cow', 'parrot']
const filtered = {};
for ( arr in animals) {
filtered[arr] = animals[arr].filter ( x => data.includes(x))
}
console.log(filtered)