Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS (ES6): Filter array based on nested array attributes

I have an array, which looks like this:

const persons = [
  {
    name: "Joe",
    animals: [
      {species: "dog", name: "Bolt"},
      {species: "cat", name: "Billy"},
    ]
  },
  {
    name: "Bob",
    animals: [
      {species: "dog", name: "Snoopy"}
    ]
  }
];

Now I want to filter based on the species. For example: every person which has a cat, should be returned:

const result = [
  {
    name: "Joe",
    animals: [
      {species: "dog", name: "Bolt"},
      {species: "cat", name: "Billy"},
    ]
  }
];

I have tried with the the filter() method like this:

const result = persons.filter(p => p.animals.filter(s => s.species === 'cat'))

But this doesn't return the desired result (it returns both persons).

How can I filter the array bases on an attribute of a nested array?

like image 708
Nibor Avatar asked Mar 14 '18 14:03

Nibor


2 Answers

Your inner filter still returns a "truthy" value (empty array) for the dog person. Add .length so that no results becomes 0 ("falsey")

const result = persons.filter(p => p.animals.filter(s => s.species === 'cat').length)

Edit: Per comments and several other answers, since the goal is to get a truthy value from the inner loop, .some would get the job done even better because it directly returns true if any items match.

const result = persons.filter(p => p.animals.some(s => s.species === 'cat'))

like image 73
veratti Avatar answered Oct 08 '22 22:10

veratti


You might want to use some'

 persons.filter(p => p.animals.some(s => s.species === 'cat'))
like image 4
Jonas Wilms Avatar answered Oct 08 '22 22:10

Jonas Wilms