简体   繁体   中英

JavaScript how filter nested object's array

I've this array.

 const items = [ { text: "Dashboard", roles: ["manager", "staff"] }, { text: "User management", roles: ["admin", "manager", "staff"], children: [ { text: "Create Suburb", roles: ["manager", "admin"] }, { text: "View and Update Suburb", roles: ["staff"] }, { text: "Create shoping mall" } ] } ];

I want to filter this the role name both in the root objects and children array's objects.

If I pass the staff as my parameter, my expected output is this

 const items = [ { text: "Dashboard", roles: ["manager", "staff"] }, { text: "User management", roles: ["admin", "manager", "staff"], children: [ { text: "View and Update Suburb", roles: ["staff"] } ] } ];

What I did upto now is

const data = items.filter(element => {
  return element.roles.includes("staff");
});

This basically filter the root objects. But not filter the nested children array's object. How do I achieve this using JS?

Try using recursion(works fine if children also has children )

 const items = [ { text: "Dashboard", roles: ["manager", "staff"] }, { text: "User management", roles: ["admin", "manager", "staff"], children: [ { text: "Create Suburb", roles: ["manager", "admin"] }, { text: "View and Update Suburb", roles: ["staff"] }, { text: "Create shoping mall" } ] } ]; // recursive filter function filter(group, role){ return group.filter(item => { if(item.children){ item.children = filter(item.children, role) } return item.roles && item.roles.includes(role); }); } const data = filter(items, 'staff'); console.log(data); 

For these king of array manipulations I fine reduce is the better way.

 const items = [ { text: 'Dashboard', roles: ['manager', 'staff'] }, { text: 'User management', roles: ['admin', 'manager', 'staff'], children: [ { text: 'Create Suburb', roles: ['manager', 'admin'] }, { text: 'View and Update Suburb', roles: ['staff'] }, { text: 'Create shoping mall' } ] } ] function filterWithRoles(data,role) { return items.reduce((acc, item) => { if (item.roles.includes(role)) { item.children = item.children && item.children.filter(child => child.roles && child.roles.includes(role)) acc.push(item) } return acc }, []) } console.log(JSON.stringify(filterWithRoles(items,'staff'), null, 2)) 

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