数组转成树结构

18 阅读1分钟

递归实现(时间复杂度O(n²)) 

最直观的方式是通过递归遍历构建树,适合数据量小的场景。

核心逻辑是: 遍历数组找到当前层节点

 递归查找每个节点的子节点 将子节点挂载到children属性 

哈希表优化(时间复杂度O(n)) 高性能方案使用对象存储节点引用,

只需两次遍历: 第一次遍历建立id到节点的映射

 第二次遍历通过parentId建立父子关系 根节点通过parentId=null或其他标识确定 路径字符串处理 特殊场景如文件路径转换,需要按分隔符拆分后逐级构建5: 按"/"或""分割路径 维护当前层级节点字典 缺失节点时自动创建中间层级 TypeScript增强版 支持配置字段名的通用方法3: 可自定义id/parentId/children字段名 使用childrenListMap存储父子关系 通过nodeIds快速查找节点 性能对比: 递归法代码简洁但性能最差9 哈希表法最优,适合万级数据量413 路径处理需要特殊算法设计

function arrayToTree(items, idKey = 'id', parentKey = 'parentId') {
  const tree = [];
  const lookup = {};
  
  items.forEach(item => {
    const itemId = item[idKey];
    lookup[itemId] = { ...item, children: [] };
  });

  items.forEach(item => {
    const parentId = item[parentKey];
    if (parentId === null || !lookup[parentId]) {
      tree.push(lookup[item[idKey]]);
    } else {
      lookup[parentId].children.push(lookup[item[idKey]]);
    }
  });
  return tree;
}

function arrayToTree(items) {  const map = {}  const tree = []  items.forEach((item) => {    map[item.Name] = { ...item, children: [] }  })  items.forEach((item) => {    if (item.ParentDir && map[item.ParentDir]) {      map[item.ParentDir].children.push(map[item.Name])    } else if (!item.ParentDir) {      tree.push(map[item.Name])    }  })  return tree}