我有一个对象数组。每个对象都有 hasPermission
属性和 children
属性。
children 属性也是一个对象数组,每个对象都有 hasPermission
属性。
我的数组是这样的:
const navigationMenus = [
{
hasPermission: false,
name: 'Main',
type: 'section',
children: [
{
hasPermission: true,
name: 'Test',
type: 'item',
link: '/test'
}
]
},
{
hasPermission: true,
name: 'Master',
type: 'section',
children: [
{
hasPermission: true,
name: 'Operator Group',
type: 'item',
link: '/operator-group'
},
{
hasPermission: false,
name: 'Operation Group',
type: 'item',
link: '/operation-group'
}
]
}
];
基于 hasPermission
属性,我想要另一个数组,它只包含 hasPermission
属性为真的那些对象。
我尝试过这种方法。
const permittedNavigationMenus = []
for (let i = 0; i < navigationMenus.length; i++) {
const section = navigationMenus[i];
if (section.hasPermission) {
const permittedSection = {
name: section.name,
type: section.type,
children: []
}
for (let j = 0; j < section.children.length; j++) {
const item = section.children[j]
if (item.hasPermission) {
permittedSection.children.push(item)
}
}
permittedNavigationMenus.push(permittedSection)
}
}
console.log(JSON.stringify(permittedNavigationMenus, null, 2))
有没有更好的解决方案?
答案 0 :(得分:1)
一个简单的递归函数就可以做到:
const navigationMenus =
[ { hasPermission: false, name: 'Main', type: 'section', children:
[ { hasPermission: true, name: 'Test', type: 'item', link: '/test' } ]
}
, { hasPermission: true, name: 'Master', type: 'section', children:
[ { hasPermission: true, name: 'Operator Group', type: 'item', link: '/operator-group' }
, { hasPermission: false, name: 'Operation Group', type: 'item', link: '/operation-group' }
] } ]
const navigationMenusTrue = []
function runArray(arr,parent)
{
arr.forEach(({children,...info}) =>
{
if (info.hasPermission)
{
let newRow = {...info}
parent.push(newRow)
if (children)
{
let xChilds = []
newRow.children = xChilds
runArray(children,xChilds)
}
}
})
}
runArray(navigationMenus,navigationMenusTrue)
console.log( navigationMenusTrue )
.as-console-wrapper {max-height: 100%!important;top:0 }
答案 1 :(得分:1)
这是一个使用 Array#reduce()
const
filterByPermission = (arr) => {
return arr.reduce((a, o) => {
if (o.hasPermission) {
const _o = o?.children?.length
? { ...o, children: filterByPermission(o.children) }
: { ...o };
a.push(_o);
}
return a;
}, [])
},
navigationMenus = [{ hasPermission: false, name: 'Main', type: 'section', children: [{ hasPermission: true, name: 'Test', type: 'item', link: '/test' }] }, { hasPermission: true, name: 'Master', type: 'section', children: [{ hasPermission: true, name: 'Operator Group', type: 'item', link: '/operator-group' }, { hasPermission: false, name: 'Operation Group', type: 'item', link: '/operation-group' }] }],
result = filterByPermission(navigationMenus);
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:1)
需要使用递归
const navigationMenus = [
{
hasPermission: false,
name: 'Main',
type: 'section',
children: [
{
hasPermission: true,
name: 'Test',
type: 'item',
link: '/test'
}
]
},
{
hasPermission: true,
name: 'Master',
type: 'section',
children: [
{
hasPermission: true,
name: 'Operator Group1',
type: 'item',
link: '/operator-group'
},
{
hasPermission: false,
name: 'Operation Group2',
type: 'item',
link: '/operation-group',
children: [
{
hasPermission: true,
name: 'Operator Group3',
type: 'item',
link: '/operator-group'
},
{
hasPermission: false,
name: 'Operation Group4',
type: 'item',
link: '/operation-group'
}
]
}
]
}
];
function filterRec(arr = []) {
return arr.map(el => {
const elem = el.hasPermission && el
const children = filterRec(el.children)
const result = ({ ...elem, ...(children.length && ({children}) || {}) })
return Object.keys(result).length && result
}).filter(Boolean)
}
// or without empty children key
// /function filterRec(arr = []) {
// return arr.reduce((acc, el) => {
// let result = el.hasPermission && el
// const children = filterRec(el.children)
// if (result && children.length) {
// result.children = children
// } else if (!result) {
// result = children
// }
// return acc.concat(result).filter(Boolean)
// }, [])
// }
console.log(filterRec(navigationMenus))
答案 3 :(得分:0)
您可以使用 .reduce()
一次性完成:
const permittedNavigationMenus = navigationMenus.reduce(
(acc, cur) => {
if (cur.hasPermission) {
acc.push({
...cur,
children: cur.children.filter(({ hasPermission }) => hasPermission)
})
}
return acc;
},
[]
);