如何将数组形式的对象树转换为带完整路径的层级树形结构?
问题描述
需要将如下数组形式的输入:
const input = [ ['Item 1'], ['Item 1', 'Item 2'], ['Item 1', 'Item 3'], ['Item 1', 'Item 4', 'Item 5'], ['Item 8', 'Item 9'], ['Item 10', 'Item 11', 'Item 12', 'Item 13'] ]
转换为包含name和path属性的层级树形结构,预期输出如下:
const output = [ { name: 'Item 1', path: 'Item 1', children: [ { name: 'Item 2', path: 'Item 1, Item 2' }, { name: 'Item 3', path: 'Item 1, Item 3' }, { name: 'Item 4', path: 'Item 1, Item 4', children: [ { name: 'Item 5', path: 'Item 1, Item 4, Item 5' } ] }, ] }, { name: 'Item 8', path: 'Item 8', children: [ { name: 'Item 9', path: 'Item 8, Item 9' } ] }, { name: 'Item 10', path: 'Item 10', children: [ { name: 'Item 11', path: 'Item 10, Item 11', children: [ { name: 'Item 12', path: 'Item 10, Item 11, Item 12', children: [ { name: 'Item 13', path: 'Item 10, Item 11, Item 12, Item 13' } ] } ] }, ] } ]
尝试的代码无法正确生成超过两级的路径,递归方案也没能同时搞定树形结构和path属性,需要可行的解决方法。
解决方案
可以通过迭代遍历+层级追踪的方式实现,核心思路是:
- 维护一个根节点数组作为最终结果
- 对每个输入的路径数组,从根节点开始逐层查找或创建节点
- 每一层节点的
path基于父节点的path拼接生成
实现代码如下:
function buildTree(input) { const root = []; input.forEach(pathArr => { let currentLevel = root; let parentPath = ''; pathArr.forEach((item, index) => { // 检查当前层级是否已存在该节点 let existingNode = currentLevel.find(node => node.name === item); if (!existingNode) { // 生成当前节点的path:如果是第一个节点直接用item,否则拼接父路径 const currentPath = parentPath ? `${parentPath}, ${item}` : item; existingNode = { name: item, path: currentPath }; currentLevel.push(existingNode); } // 准备下一层级的追踪:如果有子节点就用子节点数组,否则初始化空数组 if (index < pathArr.length - 1) { existingNode.children = existingNode.children || []; currentLevel = existingNode.children; parentPath = existingNode.path; } }); }); return root; } // 使用示例 const input = [ ['Item 1'], ['Item 1', 'Item 2'], ['Item 1', 'Item 3'], ['Item 1', 'Item 4', 'Item 5'], ['Item 8', 'Item 9'], ['Item 10', 'Item 11', 'Item 12', 'Item 13'] ]; const output = buildTree(input); console.log(output);
代码说明
- 根节点初始化:
root数组存储所有顶级节点 - 遍历每条路径:对输入中的每个路径数组,从根层级开始处理
- 节点查找/创建:在当前层级检查是否存在同名节点,不存在则创建,同时根据父路径生成当前节点的
path - 层级切换:如果当前不是路径的最后一个元素,切换到子节点层级,更新父路径为当前节点的
path,继续处理下一个元素 - 子节点处理:只有当需要处理下一层元素时,才初始化
children数组,避免空数组冗余
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

