Home > OS >  Javascript - Filter object containing arrays with value from another array
Javascript - Filter object containing arrays with value from another array

Time:06-20

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)

  • Related