js用递归的方式过滤数组

最近遇到一个问题,先贴代码

[
    { path: 'levelone', name: '第一级', iconClass:'fa-navicon', isRoot: true, subMenus:[
        { path: 'leveltwo', name: '第二级', iconClass:'fa-navicon',subMenus:[
            { path: 'levelthree', name: '第三级', roles:['admin'], iconClass:'fa-navicon' }
        ]},
        { path: 'leveltwo_R', name: '第二级_R', iconClass:'fa-navicon' }
    ]},
    { path: 'user', name: '用户管理', roles:['admin'], iconClass:'fa-language', isRoot: true },
    { path: 'dictionary', name: '字典管理', roles:['admin'], iconClass:'fa-language', isRoot: true },
    { path: 'role', name: '角色管理', roles:['admin'], iconClass:'fa-vcard', isRoot: true },
    { path: 'outline', name: '违规管理', roles:['admin'], iconClass:'fa-exclamation-triangle', isRoot: true }
]

我有这样的一个数组,且数组层级未知,其叶子节点上都roles属性,如果没有或不包含admin,则需要筛选掉。请问怎么解决?这里肯定是需要用递归来实现的,我用了filter,但是在有subMenus的节点上,我用的是some来过滤

filterRoutes(route,role) {
  if(route.subMenus && route.subMenus.length){
    return route.subMenus.some((item) => {
      return this.filterRoutes(item,role);
    });
  }else{
    return route.roles && -1 < route.roles.indexOf(role);
  }
}

导致leveltwo_R这个节点没有被遍历,就是这里没有想明白,求指点

阅读 6.3k
3 个回答

var f = item => {
    if (item['subMenus']) {
        item['subMenus'] = item['subMenus'].filter(f);
        return true;
    } else if (item['roles']) {
        return item['roles'].indexOf('admin') !== -1;
    } else {
        return false;
    }
}

var result = data.filter(f);
var data = [
        {
            path: 'levelone', name: '第一级', iconClass: 'fa-navicon', isRoot: true, subMenus: [
                {
                    path: 'leveltwo', name: '第二级', iconClass: 'fa-navicon', subMenus: [
                        { path: 'levelthree', name: '第三级', roles: ['admin'], iconClass: 'fa-navicon' }
                    ]
                },
                { path: 'leveltwo_R', name: '第二级_R', iconClass: 'fa-navicon' }
            ]
        },
        { path: 'user', name: '用户管理', roles: ['admin'], iconClass: 'fa-language', isRoot: true },
        { path: 'dictionary', name: '字典管理', roles: ['admin'], iconClass: 'fa-language', isRoot: true },
        { path: 'role', name: '角色管理', roles: ['admin'], iconClass: 'fa-vcard', isRoot: true },
        { path: 'outline', name: '违规管理', roles: ['admin'], iconClass: 'fa-exclamation-triangle', isRoot: true }
    ]
    var dataArr = [];
    function filter(arr) {
        for (let i = 0; i < arr.length; i++) {
            if(arr[i].subMenus && arr[i].subMenus.length){
                filter(arr[i].subMenus);
            }else{
                if(!(arr[i].roles && arr[i].roles.includes('admin'))){
                    dataArr.push(arr[i]);
                    arr.splice(i, 1)
                }
            }
        }
    }
    filter(data);
    console.log(data)
    console.log(dataArr)

在data里剔除了不符合条件的数据放到dataArr里面,不知道是不是你想要的结果

some是有一个返回true就停止执行了,所以第二个没有去检测

var arr = [
        { path: 'levelone', name: '第一级', iconClass:'fa-navicon', isRoot: true, subMenus:[
            { path: 'leveltwo', name: '第二级', iconClass:'fa-navicon',subMenus:[
                { path: 'levelthree', name: '第三级', roles:['admin'], iconClass:'fa-navicon' }
            ]},
            { path: 'leveltwo_R', name: '第二级_R', iconClass:'fa-navicon' }
        ]},
        { path: 'user', name: '用户管理', roles:['admin'], iconClass:'fa-language', isRoot: true },
        { path: 'dictionary', name: '字典管理', roles:['admin'], iconClass:'fa-language', isRoot: true },
        { path: 'role', name: '角色管理', iconClass:'fa-vcard', isRoot: true , subMenus:[
            { path: 'leveltwo_R', name: '第二级_R', iconClass:'fa-navicon' },
            { path: 'leveltwo_R', name: '第二级_R', iconClass:'fa-navicon' },
            { path: 'leveltwo_R', name: '第二级_R', iconClass:'fa-navicon' }
        ]},
        { path: 'outline', name: '违规管理', roles:['admin'], iconClass:'fa-exclamation-triangle', isRoot: true }
    ]

function filterRoutes(route,role) {
    var bool;
    for(var i=route.length-1;i>=0;i--){
        bool = !(route[i].roles && route[i].roles.indexOf(role)>-1);
        if(route[i].subMenus && route[i].subMenus.length){
            filterRoutes(route[i].subMenus,role)
            bool && route[i].subMenus.length == 0 && route.splice(i,1)
        }else{
            bool && route.splice(i,1)
        }
    }
}
filterRoutes(arr,'admin')
console.log(arr)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题