求助:基于用户角色过滤JavaScript嵌套数组
按用户角色过滤多级菜单数组问题
问题详情
服务器返回的菜单数组:
const mainObj = [ { "title": "Merchant", "role": ["0"], "subMenu": [{ "subMenu1": "Initiate", "role": ["1"] }] }, { "title": "Prepaid", "role": ["1"], "subMenu": [{ "subMenu1": "Merch1", "role": ["2"] }, { "subMenu1": "Merch3", "role": ["1"] } ] } ];
用户角色标识:
const userRole = {"userFlag": 1};
尝试的错误代码:
const result = mainObj.filter(role => role.find(group => userRole.userFlag.includes(group.role)))
预期输出:
[ { "title":"Prepaid", "role":[ "1" ], "subMenu":[ { "subMenu1":"Merch3", "role":[ "1" ] } ] } ]
错误原因
- 参数命名混乱:
filter回调里的role实际是菜单对象,不是角色;find方法使用错误,当前对象没有group属性 - 类型不匹配:用户角色是数字
1,菜单里的role是字符串数组,直接对比会失败 - 方法误用:
userRole.userFlag是数字,不能调用数组的includes方法,应该反过来检查菜单的role数组是否包含用户角色的字符串形式 - 未处理子菜单:原代码只过滤了主菜单层级,没有递归过滤子菜单
正确实现代码
const userRole = {"userFlag": 1}; // 统一角色类型为字符串,和菜单数组中的role元素匹配 const allowedRole = String(userRole.userFlag); // 递归过滤菜单的函数 function filterMenu(menuList) { return menuList // 过滤当前层级中包含允许角色的菜单 .filter(item => item.role.includes(allowedRole)) // 保留菜单原有属性,同时处理子菜单 .map(item => { if (item.subMenu) { return { ...item, subMenu: filterMenu(item.subMenu) }; } return item; }); } const mainObj = [ { "title": "Merchant", "role": ["0"], "subMenu": [{ "subMenu1": "Initiate", "role": ["1"] }] }, { "title": "Prepaid", "role": ["1"], "subMenu": [{ "subMenu1": "Merch1", "role": ["2"] }, { "subMenu1": "Merch3", "role": ["1"] } ] } ]; const result = filterMenu(mainObj); console.log(JSON.stringify(result, null, 2));
代码说明
- 先将用户的数字角色转为字符串,确保和菜单中
role数组的元素类型一致,避免类型对比错误 filterMenu函数支持递归处理多级菜单:先过滤当前层级的菜单,再对每个符合条件的菜单递归处理其子菜单- 使用
map和扩展运算符...item保留菜单的原有属性,只替换过滤后的子菜单,保证数据结构完整
内容的提问来源于stack exchange,提问作者vishnu
相关产品推荐
相关产品推荐

