You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持无限子菜单的递归菜单生成函数?MongoDB场景遇问题

递归生成层级菜单问题

需求说明

实现一个递归函数,生成层级菜单结构:

  • 当菜单项的relatedId(父ID引用)未定义时,作为主菜单
  • 当某菜单项的id与另一项的relatedId匹配时,作为对应父菜单的子菜单
    最终生成可无限扩展的层级JSON结构。

现有代码(无法正常运行)

const getMastersMenu = await Menu.find()
let MenuArray: any = []
let SubMenuArray : any = []
getMastersMenu.map((menu: any) => { 
    MenuArray.push({id: menu._id.toString(), name : menu.name, relatedId : menu?.relatedId})
})

const findRecursiveMenus = (menuItems: any) => {
    if (menuItems) {
        let newList: any = [];
        menuItems.map((menu: any) => {
            const findRelationship = menuItems.some((el: any, i: any) => {
                return el.id === menu.relatedId
            })

            console.log(findRelationship)

            if(menu.relatedId === undefined){
                let ObjectSubmenu = {id: menu.id, name : menu.name}
                newList.push(ObjectSubmenu)
            } else if (findRelationship){
                let returnedList = findRecursiveMenus({submenus : {id: menu.id, name : menu.name, relatedId : menu.relatedId}})                    
                newList.push(returnedList)
            }
        })
        return newList;
    }
}

代码问题分析

  1. 递归传参错误:递归调用时传入单个对象而非子项数组,导致无法遍历子菜单
  2. 父节点判断逻辑颠倒:findRelationship仅判断当前菜单的父节点是否存在,未处理当前菜单作为父节点的子项
  3. 缺少子菜单容器:主菜单对象未添加submenus属性,无法挂载子菜单
  4. 效率低下:每次遍历用some查找,重复遍历导致时间复杂度高

修正后的代码

// 获取并转换菜单数据,确保ID类型统一
const getMastersMenu = await Menu.find();
const menuItems = getMastersMenu.map(menu => ({
    id: menu._id.toString(),
    name: menu.name,
    relatedId: menu?.relatedId?.toString() // 统一为字符串类型,匹配id格式
}));

// 构建ID映射表,快速查找子项
const menuIdMap = new Map(menuItems.map(item => [item.id, item]));

// 递归生成层级菜单
const buildHierarchicalMenu = (parentId: string | undefined) => {
    // 筛选当前父节点下的所有子项
    const childItems = menuItems.filter(item => item.relatedId === parentId);
    
    // 给每个子项递归生成自身的子菜单
    return childItems.map(item => ({
        ...item,
        submenus: buildHierarchicalMenu(item.id)
    }));
};

// 生成最终的层级菜单(主菜单为relatedId未定义的项)
const finalMenu = buildHierarchicalMenu(undefined);
console.log(finalMenu);

代码说明

  1. ID映射优化:用Map存储菜单ID与对应对象,避免重复遍历查找,提升处理效率
  2. 递归逻辑清晰:buildHierarchicalMenu接收父ID,筛选对应子项后递归生成子菜单,结构层级明确
  3. 类型统一:将relatedId转为字符串,确保和id类型匹配,避免因类型差异导致的匹配失败
  4. 结构统一:每个菜单项自动生成submenus属性,无子项时为空数组,输出结构规范可扩展

内容的提问来源于stack exchange,提问作者Breno Sobral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:05:25