如何基于扁平页面数组递归生成任意层级HTML站点地图
无限层级站点地图生成通用实现
原实现硬编码了4层嵌套的处理逻辑,不管是树结构构建还是HTML渲染都靠写死的多层循环实现,不仅代码冗余,嵌套深度超过4层就会直接失效,可维护性很差。可以用「Map映射建树+递归渲染」的思路重写,完全不需要限制页面嵌套深度。
核心逻辑
- 预处理所有页面数据,用
Map建立URL到页面对象的映射,查找父节点时不需要多层遍历,时间复杂度更低 - 遍历所有页面,根据URL自动计算父级路径,把当前页面挂载到对应父节点的子列表中,自动完成任意深度的树结构构建
- 用递归函数遍历树结构渲染HTML,遇到子节点自动递归生成嵌套列表,不需要写死多层循环逻辑
完整代码
const generateSitemap = function(pages) { const pageMap = new Map(); const rootPages = []; // 初始化所有页面节点,存入映射表 pages.forEach(page => { pageMap.set(page.url, { title: page.name, url: page.url, children: [] }); }); // 构建层级树 pageMap.forEach((pageNode, url) => { // 拆分URL路径段 const pathSegments = url.replace(/^\/|\/$/g, '').split('/'); // 一级页面直接加入根节点列表 if (pathSegments.length === 1) { rootPages.push(pageNode); return; } // 计算父级URL const parentUrl = `/${pathSegments.slice(0, -1).join('/')}/`; const parentNode = pageMap.get(parentUrl); // 挂载到父节点下 if (parentNode) { parentNode.children.push(pageNode); } }); // 递归渲染嵌套列表HTML const renderNodeList = (nodeList) => { if (!nodeList.length) return ''; let html = '<ul>'; nodeList.forEach(node => { html += `<li><a href="${node.url}">${node.title}</a>`; if (node.children.length) { html += renderNodeList(node.children); } html += '</li>'; }); html += '</ul>'; return html; }; return renderNodeList(rootPages); }; // 测试示例 const pages = [ { "name": "Page 1", "url": "/page-1/" }, { "name": "Page 2", "url": "/page-2/" }, { "name": "Child 1", "url": "/page-1/child-1/" }, { "name": "Child 2", "url": "/page-1/child-1/child-2/" }, { "name": "Child 3", "url": "/page-1/child-1/child-2/child-3/" } ]; // 执行后输出的HTML和需求给出的预期结构完全一致 console.log(generateSitemap(pages));
方案特点
- 无嵌套深度限制,支持任意层级的页面结构,后续新增更深层级的页面不需要修改核心逻辑
- 代码量比原实现减少70%以上,没有重复判断和重复循环逻辑,后续维护成本极低
- 用Map做节点索引,相比原实现的多层全量遍历,页面数量大时性能提升明显
- 如果需要处理父节点不存在的异常场景,只需要在挂载父节点的分支加对应的容错逻辑即可,扩展方便
内容的提问来源于stack exchange,提问作者tay
相关产品推荐
相关产品推荐

