JavaScript一维JSON数组按path属性重排为指定结构(非重复问题)
把一维JSON数组按path属性转成嵌套结构的实用方案
我之前也碰到过一模一样的需求——把一堆带path属性的扁平JSON对象转成嵌套结构,一开始用filter和find来回找父节点,代码乱得像一团麻,后来发现用映射对象配合遍历的方式既清晰又高效,给你分享下具体实现:
核心思路
- 先给每个节点初始化
children空数组,用来存子节点 - 搞一个映射对象,把每个
path和对应的节点绑定起来,这样找父节点的时候不用反复遍历数组,直接通过path就能快速定位,性能提升特别明显 - 把每个节点的
path拆成路径片段,找到它的父节点,然后把当前节点塞到父节点的children里
代码示例(JavaScript)
假设你的扁平数组长这样:
const flatNodes = [ { id: 1, path: "home", label: "首页" }, { id: 2, path: "home>products", label: "产品列表" }, { id: 3, path: "home>products>laptops", label: "笔记本电脑" }, { id: 4, path: "home>products>phones", label: "手机" }, { id: 5, path: "home>about", label: "关于我们" }, { id: 6, path: "home>about>team", label: "团队介绍" } ];
处理的核心代码:
function buildNestedTree(flatArray) { // 第一步:给每个节点加children,同时建立path到节点的映射表 const nodeMap = {}; const processed = flatArray.map(node => { const newNode = { ...node, children: [] }; nodeMap[node.path] = newNode; return newNode; }); // 第二步:遍历每个节点,挂载到父节点下 processed.forEach(node => { const pathParts = node.path.split(">"); // 只有非根节点才需要找父节点 if (pathParts.length > 1) { // 生成父节点的path:去掉最后一段路径 const parentPath = pathParts.slice(0, -1).join(">"); const parentNode = nodeMap[parentPath]; // 找到父节点就把当前节点加进去 if (parentNode) { parentNode.children.push(node); } } }); // 第三步:返回所有根节点(path只有一段的节点) return processed.filter(node => node.path.split(">").length === 1); } // 调用函数得到嵌套结构 const nestedTree = buildNestedTree(flatNodes); console.log(JSON.stringify(nestedTree, null, 2));
关键细节说明
- 映射表
nodeMap:这是解决代码混乱的关键!之前用find每次都要遍历整个数组,数组大了特别卡,现在用nodeMap直接通过path取节点,时间复杂度降到O(1),代码也清爽多了。 - 路径拆分:如果你的
path用的不是>当分隔符,比如"/"或者".",只需要把split(">")换成对应的分隔符就行,兼容性很强。 - 容错处理:代码里加了
if (parentNode)的判断,如果遇到无效的path(比如父节点不存在),会自动跳过挂载,不会报错,你也可以根据需求加个console提示。
内容的提问来源于stack exchange,提问作者Amine Kacem
相关产品推荐
相关产品推荐

