根据对象的值筛选JavaScript深度嵌套的对象数组
我的菜单结构如下:根据对象的值筛选JavaScript深度嵌套的对象数组,javascript,arrays,filtering,Javascript,Arrays,Filtering,我的菜单结构如下: const menu = [ { title: 'Supervisor Dashboard', link: '/dashboard/supervisor-dashboard', slug: '/dashboard/supervisor-dashboard' }, { title: 'User Dashboard', link: '/dashboard/user-dashboard', slug: '/dashboar
const menu = [
{
title: 'Supervisor Dashboard',
link: '/dashboard/supervisor-dashboard',
slug: '/dashboard/supervisor-dashboard'
},
{
title: 'User Dashboard',
link: '/dashboard/user-dashboard',
slug: '/dashboard/user-dashboard'
},
{
title: 'Inventory',
slug: '/inventory',
children: [
{
title: 'Add Inventory',
link: '/inventory/add-inventory',
slug: '/inventory/add-inventory'
},
{
title: 'Remove Inventory',
link: '/inventory/remove-inventory',
slug: '/inventory/remove-inventory'
},
]
},
{
title: 'Membership',
slug: '/membership',
children: [
{
title: 'Program A',
slug: '/membership/program-a',
children: [
{
title: 'View Membership',
link: '/membership/program-a/view',
slug: '/membership/program-a/view'
},
{
title: 'Add Membership',
link: '/membership/program-a/add',
slug: '/membership/program-a/add'
},
{
title: 'Delete Membership',
link: '/membership/program-a/delete',
slug: '/membership/program-a/delete'
}
]
},
{
title: 'Program B',
slug: '/membership/program-b',
children: [
{
title: 'View Membership',
link: '/membership/program-b/view',
slug: '/membership/program-b/view'
},
{
title: 'Add Membership',
link: '/membership/program-b/add',
slug: '/membership/program-b/add'
},
{
title: 'Delete Membership',
link: '/membership/program-b/delete',
slug: '/membership/program-b/delete'
}
]
}
],
},
];
const allowed_slug = [
'/dashboard/user-dashboard',
'/inventory/add-inventory',
'/membership/program-b/view',
'/membership/program-b/add'
];
我想过滤菜单,即只显示授予用户的任何内容。用户只能根据允许的slug查看菜单,如下所示:
const menu = [
{
title: 'Supervisor Dashboard',
link: '/dashboard/supervisor-dashboard',
slug: '/dashboard/supervisor-dashboard'
},
{
title: 'User Dashboard',
link: '/dashboard/user-dashboard',
slug: '/dashboard/user-dashboard'
},
{
title: 'Inventory',
slug: '/inventory',
children: [
{
title: 'Add Inventory',
link: '/inventory/add-inventory',
slug: '/inventory/add-inventory'
},
{
title: 'Remove Inventory',
link: '/inventory/remove-inventory',
slug: '/inventory/remove-inventory'
},
]
},
{
title: 'Membership',
slug: '/membership',
children: [
{
title: 'Program A',
slug: '/membership/program-a',
children: [
{
title: 'View Membership',
link: '/membership/program-a/view',
slug: '/membership/program-a/view'
},
{
title: 'Add Membership',
link: '/membership/program-a/add',
slug: '/membership/program-a/add'
},
{
title: 'Delete Membership',
link: '/membership/program-a/delete',
slug: '/membership/program-a/delete'
}
]
},
{
title: 'Program B',
slug: '/membership/program-b',
children: [
{
title: 'View Membership',
link: '/membership/program-b/view',
slug: '/membership/program-b/view'
},
{
title: 'Add Membership',
link: '/membership/program-b/add',
slug: '/membership/program-b/add'
},
{
title: 'Delete Membership',
link: '/membership/program-b/delete',
slug: '/membership/program-b/delete'
}
]
}
],
},
];
const allowed_slug = [
'/dashboard/user-dashboard',
'/inventory/add-inventory',
'/membership/program-b/view',
'/membership/program-b/add'
];
使用.filter
我可以过滤阵列的第一层。以下是我迄今为止取得的成就:
function filterMenu(menus, allowed_slug) {
const result = menus.filter(function (menu_item) {
return allowed_slug.filter(function(slug) {
return menu_item.slug.indexOf(slug) > -1;
}).length;
});
return result;
}
理想输出应如下所示:
o
|-- User Dashboard
|-- Inventory
| `-- Add Inventory
`-- Membership
`-- Program B
|-- View Membership
`-- Add Membership
问题是,我无法过滤嵌套数组,即children和children的children。非常感谢您的帮助。:) 递归是您的朋友:
// smae signature as your function
const filterMenu = (menus, allowed) => menus
// first of all, copy & filter recursively
.map(({ title, slug, link, children }) => ({ title, slug, link, children: children && filterMenu(children, allowed) }))
// then remove all that don't have allowed children and are not allowed themself
.filter(it => it.children && it.children.length || allowed.includes(it.slug));
您可以检查一个
allowdslaug
是否以实际对象的slug开头
var菜单=[{title:'Supervisor Dashboard',链接:'/Dashboard/Supervisor Dashboard',slug:'/Dashboard/Supervisor Dashboard'},{title:'Inventory',slug:'/Inventory',子菜单:[{title:'addinventory',link:'/Inventory/addinventory',slug:'/Inventory/addinventory'},{title:'Remove Inventory',link:'/Inventory/Remove Inventory'}},{title:'Membership',slug:'/Membership',children[{title:'Program A',slug:'/Membership-A',children[{title:'View Membership',link:'/Membership/program-a/View',slug:'/Membership/program-a/View'},{title:'Add Membership',link:'/Membership/program-a/View'},{title:'Delete Membership/program-a/Delete',slug:'/Membership/program-a/Delete'},{title:'Program B',slug:'/membership/Program-B',children:[{title:'View membership',link:'/membership/Program-B/View',slug:'/membership/Program-B/View'},{title:'Add membership',link'/membership/Program-B/Add',slug:'/membership/Program-B/Add'},{title:'Delete Membership',link:'/Membership/program-b/Delete',slug:'/Membership/program-b/Delete'}]}]],允许的\'u slug=['/dashboard/user dashboard','/inventory/add inventory','/Membership/program-b/view','/Membership/program-b/add'],
过滤器=菜单=>菜单
.filter(({slug})=>允许的_slug.some(s=>s.startsWith(slug)))
.map({title,slug,children=[]})=>{
children=过滤器(children);
返回Object.assign({title,slug},children.length&&{children})
}),
结果=过滤器(菜单);
console.log(结果);
.as console wrapper{max height:100%!important;top:0;}
尝试使用此函数,看看它是否符合您的需要。它基本上使用递归函数创建一个新数组,检查每个元素是否符合Slug数组的条件:
const menu=[{title:'Supervisor Dashboard',link:'/Dashboard/Supervisor Dashboard',slug:'/Dashboard/Supervisor Dashboard'},{title:'Inventory',slug:'/Inventory',子项:[{title:'addinventory',link:'/Inventory/addinventory',slug:'/Inventory/addinventory'},{title:'Remove Inventory',link:'/Inventory/Remove Inventory'},]},{title:'Membership',slug:'/Membership',children[{title:'Program A',slug:'/Membership-A',children{title:'View Membership',link:'/Membership/program-a/View',slug:'/Membership/program-a/View'},{title:'Add Membership',link:'/Membership/program-a/View'},{title:'Delete Membership/program-a/Delete',slug:'/Membership/program-a/Delete'},{title:'Program B',slug:'/membership/Program-B',children:[{title:'View membership',link:'/membership/Program-B/View',slug:'/membership/Program-B/View'},{title:'Add membership',link'/membership/Program-B/Add',slug:'/membership/Program-B/Add'},{title:'Delete Membership',link:'/Membership/program-b/Delete',slug:'/Membership/program-b/Delete'}]}],},];const allowed_slug=['/dashboard/user dashboard','/inventory/add inventory','/Membership/program-b/view','/Membership/program-b/add'];
常量过滤器菜单=(菜单,允许)=>
menu.reduce((a,{title,link,slug,children=[])=>
(children=filterMenu(children,allowed),(children.length&(a=[…a,{title,slug,children}]))| |(allowed.includes(slug)&&(a=[…a,{title,link,slug}]),a),[]);
console.log(filterMenu(menu,allowed_slug));
使用some()
或every()
而不是filter().length
。另外,我很确定您正在查找菜单项.slug.indexOf(slug)==0
(不是=0
),或者菜单项.slug.startsWith(slug)
为什么仪表板没有缩进?@NinaScholz这就是结构。我想添加一些动态结构。@Bergi这仍然不能解决嵌套过滤问题。我结合多个数组原型函数尝试了一天多。@NinaScholz事实上,这与您在中的回答非常相似。只是结构更加嵌套ed.谢谢你的回答。它可以工作,但并不完全有效。就像@jonaswillms answer一样。它在每个菜单中创建一个空的子数组,这打破了我的样式。巧妙地使用对象。分配;)只需删除过滤器菜单函数中的一个额外括号。这过滤器菜单(子菜单),允许)
应该是filterMenu(儿童,允许)
。