JSON遗留树形数据合并与节点修复问题求助(JavaScript)
解决方案:合并重复节点并调整运输树结构
核心思路
- 先通过节点映射表收集所有节点,合并相同
loc_id的节点(保留所有子节点) - 递归遍历树结构,针对
Redistributor节点,提取其内部嵌套的FinalDestination作为直接子节点 - 修复递归逻辑,确保所有层级的子节点都被处理,避免被忽略
完整实现代码
function processShippingTree(originalTree) { // 构建loc_id到节点的映射,合并重复节点的子节点 const nodeMap = new Map(); // 遍历所有节点填充映射,处理重复节点 function traverseAndMap(node) { if (!node) return; if (nodeMap.has(node.loc_id)) { const existingNode = nodeMap.get(node.loc_id); // 合并子节点:优先保留已有子节点,补充当前节点的子节点 if (existingNode.children && node.children) { existingNode.children = [...existingNode.children, ...node.children]; } else if (node.children) { existingNode.children = node.children; } } else { // 深拷贝节点避免污染原数据 const clonedNode = JSON.parse(JSON.stringify(node)); nodeMap.set(clonedNode.loc_id, clonedNode); } // 递归处理所有子节点 if (node.children && Array.isArray(node.children)) { node.children.forEach(traverseAndMap); } } // 初始化映射表 originalTree.forEach(traverseAndMap); // 重构树结构,调整FinalDestination位置并应用合并后的节点 function restructureNode(node) { if (!node) return null; const processedNode = nodeMap.get(node.loc_id); if (processedNode.type === "Redistributor") { const finalDests = []; const otherChildren = []; if (processedNode.children && Array.isArray(processedNode.children)) { processedNode.children.forEach(child => { if (child.type === "FinalDestination") { finalDests.push(child); } else { // 递归处理非最终目的地子节点 otherChildren.push(restructureNode(child)); } }); } // 合并子节点:其他层级节点在前,最终目的地在后 processedNode.children = [...otherChildren, ...finalDests]; } else { // 处理非Redistributor节点的子节点 if (processedNode.children && Array.isArray(processedNode.children)) { processedNode.children = processedNode.children.map(restructureNode); } } return processedNode; } // 处理所有根节点 return originalTree.map(restructureNode); }
代码说明
- 节点映射合并:通过
nodeMap记录每个loc_id对应的节点,遇到重复节点时直接合并子节点,确保不会丢失任何路径信息 - 递归修复:在
restructureNode中,对所有类型节点的子节点都执行递归处理,不管子节点是否为空,彻底解决了递归失效、子节点被忽略的问题 - 目的地调整:针对
Redistributor节点,将原本嵌套在其内部的FinalDestination筛选出来,作为直接子节点挂载,符合运输路径的层级逻辑
测试示例
原始输入(模拟遗留数据)
[ { "type": "Manufacturer", "loc_id": "M1", "name": "Factory A", "children": [ { "type": "Shipper", "loc_id": "S1", "name": "Logistics Co", "children": [ { "type": "Redistributor", "loc_id": "R1", "name": "Distro Center 1", "children": [ { "type": "FinalDestination", "loc_id": "D1", "name": "Customer X" } ] }, { "type": "Redistributor", "loc_id": "R1", "name": "Distro Center 1", "children": [ { "type": "Redistributor", "loc_id": "R2", "name": "Sub Distro", "children": null } ] } ] } ] } ]
处理后输出(符合期望)
[ { "type": "Manufacturer", "loc_id": "M1", "name": "Factory A", "children": [ { "type": "Shipper", "loc_id": "S1", "name": "Logistics Co", "children": [ { "type": "Redistributor", "loc_id": "R1", "name": "Distro Center 1", "children": [ { "type": "Redistributor", "loc_id": "R2", "name": "Sub Distro", "children": null }, { "type": "FinalDestination", "loc_id": "D1", "name": "Customer X" } ] } ] } ] } ]
内容的提问来源于stack exchange,提问作者user1026498
相关产品推荐
相关产品推荐

