简体   繁体   中英

Deep filtering of nested arrays

I need to filter a nested array based on an array of string values like so:

const filters = ["Berlin", "Paris"]

This is the base array that needs to be filtered (need to filter the jobs array based on location key)

const departments = [
  {
    name: "Brand",
    children: [
      {
        name: "Marketing",
        jobs: [
          { location: "Paris", title: "Brand Manager" },
          { location: "Berlin", title: "Brand Designer" },
          { location: "New York", title: "Brand Designer" }
        ],
      },
    ],
  },
  {
    name: "Business",
    children: [
      {
        name: "People",
        jobs: [
          { location: "Paris", title: "Office Manager" },
          { location: "Berlin", title: "Office Manager" },
          { location: "New York", title: "Office Manager" }
        ],
      },
    ],
  },
];

Expected output would be:

const filteredDepartments = [
  {
    name: "Brand",
    children: [
      {
        name: "Marketing",
        jobs: [
          { location: "Paris", title: "Brand Manager" },
          { location: "Berlin", title: "Brand Designer" }
        ],
      },
    ],
  },
  {
    name: "Business",
    children: [
      {
        name: "People",
        jobs: [
          { location: "Paris", title: "Office Manager" },
          { location: "Berlin", title: "Office Manager" }
        ],
      },
    ],
  },
];

Any help/pointers would be appreciated as I'm hitting a deadend, thanks!

Something like this? It's a bit straight forward but, it works for that structure and only 2 levels deep. if you need to work for n levels, recursivity is needed.

 const filters = ["Berlin", "Paris"]; const departments = [ { name: "Brand", children: [ { name: "Marketing", jobs: [ { location: "Paris", title: "Brand Manager" }, { location: "Berlin", title: "Brand Designer" }, { location: "New York", title: "Brand Designer" } ], }, ], }, { name: "Business", children: [ { name: "People", jobs: [ { location: "Paris", title: "Office Manager" }, { location: "Berlin", title: "Office Manager" }, { location: "New York", title: "Office Manager" } ], }, ], }, ]; const filteredDepartments = departments.map(department => { department.children = department.children.map(child => { child.jobs = child.jobs.filter(job => filters.includes(job.location)); return child; }); return department; }); console.log(filteredDepartments);

Please try this code snippet. This code will not mutates the original array.

 const filters = ["Berlin", "Paris"] const departments = [ { name: "Brand", children: [ { name: "Marketing", jobs: [ { location: "Paris", title: "Brand Manager" }, { location: "Berlin", title: "Brand Designer" }, { location: "New York", title: "Brand Designer" } ], }, ], }, { name: "Business", children: [ { name: "People", jobs: [ { location: "Paris", title: "Office Manager" }, { location: "Berlin", title: "Office Manager" }, { location: "New York", title: "Office Manager" } ], }, ], }, ]; const filteredDepartments = departments.map(department => { let children = []; children = department.children.map(child => { let jobs = [...child.jobs]; jobs = jobs.filter(job => filters.includes(job.location)); return { name: child.name, jobs }; }); return { name: department.name, children }; }); console.log(filteredDepartments);

 const filters = ["Berlin", "Paris"]; const departments = [ { name: "Brand", children: [ { name: "Marketing", jobs: [ { location: "Paris", title: "Brand Manager" }, { location: "Berlin", title: "Brand Designer" }, { location: "New York", title: "Brand Designer" } ], }, ], }, { name: "Business", children: [ { name: "People", jobs: [ { location: "Paris", title: "Office Manager" }, { location: "Berlin", title: "Office Manager" }, { location: "New York", title: "Office Manager" } ], }, ], }, ]; const filteredDepartments = departments.map(({name, children}) => { const filteredChildren = children.map(({name, jobs}) => { const newJobs = jobs.filter(job => filters.includes(job.location)); return {name, jobs: newJobs}; }); return {name, children: filteredChildren}; }); console.log('filteredDepartments => ', filteredDepartments); console.log('departments =>', departments);

This answer removes a child from the children array if there are no matching jobs and also removes a department from the departments array if there are no children left.

 const departments = [ { name: "Brand", children: [ { name: "Marketing", jobs: [ { location: "Paris", title: "Brand Manager" }, { location: "Berlin", title: "Brand Designer" }, { location: "New York", title: "Brand Designer" } ], }, ], }, { name: "Business", children: [ { name: "People", jobs: [ { location: "Paris", title: "Office Manager" }, { location: "Berlin", title: "Office Manager" }, { location: "New York", title: "Office Manager" } ], }, ], }, ]; const filters = ["Berlin", "Paris"]; const filteredDepartments = []; for (const department of departments) { const children = []; for (const child of department.children) { const jobs = child.jobs.filter(({location}) => filters.includes(location)); if (jobs.length) children.push({...child, jobs}); } if (children.length) filteredDepartments.push({...department, children}); } console.log("departments", departments); console.log("filteredDepartments", filteredDepartments);

This answer makes use of object destructuring and the object spread syntax. Have a look at the linked documentation if you don't know what these are.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM