如何按顺序提取嵌套菜单对象的所有名称?递归与循环哪种方法更优?
嵌套菜单名称提取:递归 vs 循环实现?
需求说明
需要从给定的嵌套菜单对象中按顺序提取所有菜单名称,最终得到如下格式的数组:
const array = ["Menu 1","Menu 2","Menu 3","Menu 4","Menu 5","Menu 6"];
给定的菜单对象结构如下:
const obj = [ { "name": "Menu 1", "link": "link 1", "subitems": [ { "name": "Menu 2", "link": "link 2", } ] }, { "name": "Menu 3", "link": "link 3", "subitems": [ { "name": "Menu 4", "link": "link 4", "subitems": [ { "name": "Menu 5", "link": "link 5", }, { "name": "Menu 6", "link": "link 6", } ] } ] }, ];
你现有的递归代码只处理了数组层级,既没有提取name字段,也没有处理每个对象里的subitems,所以无法拿到所有菜单名称。下面给出两种可行的实现方式,并对比优劣:
一、修复后的递归实现
递归是处理嵌套结构最直观的方式,逻辑清晰,代码简洁。遍历每个菜单对象时,先把当前菜单的name加入数组,再递归处理它的subitems(如果存在):
const result = []; function extractMenuNames(menuList) { for (const menu of menuList) { // 先添加当前菜单名称 result.push(menu.name); // 存在子菜单则递归处理 if (menu.subitems && Array.isArray(menu.subitems)) { extractMenuNames(menu.subitems); } } } extractMenuNames(obj); console.log(result); // 输出 ["Menu 1","Menu 2","Menu 3","Menu 4","Menu 5","Menu 6"]
二、循环(迭代)实现
如果担心菜单层级极深导致递归栈溢出(业务中很少见,但极端场景下需要考虑),可以用迭代方式,借助栈来处理嵌套结构:
const result = []; // 用栈存储待处理的菜单,初始传入根菜单数组 const stack = [...obj]; while (stack.length > 0) { const menu = stack.pop(); result.push(menu.name); // 倒序压入子菜单,保证处理顺序和递归一致(栈是后进先出) if (menu.subitems && Array.isArray(menu.subitems)) { for (let i = menu.subitems.length - 1; i >= 0; i--) { stack.push(menu.subitems[i]); } } } console.log(result); // 输出 ["Menu 1","Menu 2","Menu 3","Menu 4","Menu 5","Menu 6"]
哪种方式更合适?
- 日常业务场景(菜单层级3-5级)优先选递归:代码易读、逻辑直观,维护成本低。
- 极端场景(菜单层级超过1000级)选迭代:避免递归栈溢出问题,性能更稳定。
一般来说,递归完全能满足业务需求,而且代码简洁易懂。
内容的提问来源于stack exchange,提问作者pradeep ecommerce
相关产品推荐
相关产品推荐

