如何使用jQuery遍历父子关系JSON数据生成指定路径格式
实现父子JSON数组生成层级路径字符串(jQuery版)
问题说明
现有包含父子关系的JSON数组如下:
var data = [ { id:'D1', parent: "", name: 'D1' },{ id:'Z1', parent: "D1", name: 'Z1' },{ id: 'T1', parent: "Z1", name: 'T1' },{ id: 'T2', parent: "Z1", name: 'T2' },{ id: 'C1', parent: "T2", name: 'C1' },{ id: 'Z2', parent: "D1", name: 'Z2' },{ id:'D2', parent: "", name: 'D2' },{ id:'Z3', parent: "D2", name: 'Z3' },{ id: 'T3', parent: "Z3", name: 'T3' },{ id: 'T4', parent: "Z3", name: 'T4' },{ id: 'C2', parent: "T3", name: 'C2' } // 更多节点... ];
需要通过jQuery处理该数据,生成以下格式的层级路径字符串:
D1-Z1-T1, D1-Z1-T2-C1, D1-Z2, D2-Z3-T3, D2-Z3-T3-C2 // 更多路径...
解决方案
实现思路
- 将数组转成以
id为键的映射对象,快速通过父节点ID定位对应节点,提升查找效率; - 遍历每个节点,向上递归追踪父节点直至根节点(
parent为空的节点),收集路径上的节点name; - 反转收集到的路径数组,用
-拼接成字符串; - 去重后输出所有符合要求的路径。
代码实现
生成所有节点的完整路径
$(function() { // 构建节点映射表,用于快速查找父节点 var nodeMap = {}; $.each(data, function(index, node) { nodeMap[node.id] = node; }); // 存储最终路径的数组 var paths = []; // 遍历每个节点生成路径 $.each(data, function(index, node) { var currentPath = []; var currentNode = node; // 向上遍历父节点 while(currentNode) { currentPath.push(currentNode.name); currentNode = nodeMap[currentNode.parent] || null; } // 反转路径并拼接成字符串 var pathStr = currentPath.reverse().join('-'); // 避免重复添加路径 if ($.inArray(pathStr, paths) === -1) { paths.push(pathStr); } }); // 输出结果 var result = paths.join(',\n'); console.log(result); // 如需插入页面元素,可使用下面的代码 // $('#target-element').text(result); });
运行后会输出所有节点的完整层级路径,示例数据对应的输出为:
D1, D1-Z1, D1-Z1-T1, D1-Z1-T2, D1-Z1-T2-C1, D1-Z2, D2, D2-Z3, D2-Z3-T3, D2-Z3-T3-C2, D2-Z3-T4
仅生成叶子节点的路径(匹配示例输出)
如果只需要生成无后代节点的路径,可添加过滤逻辑:
$(function() { var nodeMap = {}; $.each(data, function(index, node) { nodeMap[node.id] = node; }); // 先标记所有有子节点的ID var hasChildrenIds = []; $.each(data, function(index, node) { if (node.parent) { hasChildrenIds.push(node.parent); } }); var paths = []; // 仅遍历叶子节点(无后代的节点) $.each(data, function(index, node) { if ($.inArray(node.id, hasChildrenIds) === -1) { var currentPath = []; var currentNode = node; while(currentNode) { currentPath.push(currentNode.name); currentNode = nodeMap[currentNode.parent] || null; } var pathStr = currentPath.reverse().join('-'); paths.push(pathStr); } }); var result = paths.join(',\n'); console.log(result); });
此时输出会与你给出的示例一致:
D1-Z1-T1, D1-Z1-T2-C1, D1-Z2, D2-Z3-T3-C2, D2-Z3-T4
(注:若需要保留有子节点的节点路径,可自行调整过滤逻辑)
内容的提问来源于stack exchange,提问作者Mandeep Singh
相关产品推荐
相关产品推荐

