2

How do I apply filter within a filter in JavaScript while looking for values in an array within the array?

Say, I want to get all construction projects whose teams include Jane Smith.

I realize I'm inventing some crazy JavaScript here, I'm just trying to show you what I'm after.

const result = myArray.filter(x => x.type === "construction" && x.team.filter(y => y.name.includes("Jane Smith")));

Here's the array I want to filter:

[
   {
      "type": "construction",
      "name": "Project A",
      "team": [
         {
            "name": "John Doe",
            "position": "Engineer"
         },
         {
            "name": "Jane Smith",
            "position": "Architect"
         }
      ]
   },
   {
      "type": "construction",
      "name": "Project B",
      "team": [
         {
            "name": "Walt Disney",
            "position": "Creative Director"
         },
         {
            "name": "Albert Einstein",
            "position": "Scientist"
         }
      ]
   },
   {
      "type": "remodelling",
      "name": "Project C",
      "team": [
         {
            "name": "John Travolta",
            "position": "Manager"
         }
      ]
   }
]
Sam
  • 26,817
  • 58
  • 206
  • 383

2 Answers2

4

You could use Array#some for checking the team.

This proposal uses destructuring assignment for the objects.

var array = [{ type: "construction", name: "Project A", team: [{ name: "John Doe", position: "Engineer" }, { name: "Jane Smith", position: "Architect" }] }, { type: "construction", name: "Project B", team: [{ name: "Walt Disney", position: "Creative Director" }, { name: "Albert Einstein", position: "Scientist" }] }, { type: "remodelling", name: "Project C", team: [{ name: "John Travolta", position: "Manager" }] }],
    result = array.filter(({ type, team }) =>
        type === "construction" && team.some(({ name }) => name === "Jane Smith"));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • 2
    I think it should be `name === "Jane Smith"` rather than `name.includes("Jane Smith")`. Unless we want to match against, for example, "Jane Smithers". – sjw Jul 19 '18 at 20:15
  • This seems very nice and clean -- with @thesilkworm's suggestion. I'm testing it. Once I make sure it's working, I'll accept yours and the answer. Thank you! – Sam Jul 19 '18 at 20:16
  • Works beautifully and the structure is easy to understand. Thank you! – Sam Jul 19 '18 at 20:22
1

Maybe something like the following?

const result = myArray.filter(x => x.type === "construction" && x.team.filter(y => y.name.includes("Jane Smith")).length > 0);

Basically I'm just checking to see if that new filtered array length is greater than 0.

Charlie Fish
  • 18,491
  • 19
  • 86
  • 179