编辑代码

interface TreeNode {
  id: number;
  name: string;
  parentId: number | null;
  children?: TreeNode[];
}

// 创建一个映射,以便于通过 id 快速查找节点
function createNodeMap(nodes: TreeNode[]): Map<number, TreeNode> {
  const nodeMap = new Map<number, TreeNode>();
  nodes.forEach(node => {
    nodeMap.set(node.id, { ...node, children: [] });
  });
  return nodeMap;
}

// 递归构建树结构
function buildTree(nodeMap: Map<number, TreeNode>, parentId: number | null): TreeNode[] {
  const children: TreeNode[] = [];
  nodeMap.forEach(node => {
    if (node.parentId === parentId) {
      const childNode = nodeMap.get(node.id)!;
      childNode.children = buildTree(nodeMap, node.id);
      children.push(childNode);
    }
  });
  return children;
}

// 主函数,将扁平的节点数组转换为树形结构
function arrayToTree(items: TreeNode[]): TreeNode[] {
  const nodeMap = createNodeMap(items);
  const roots: TreeNode[] = [];
  nodeMap.forEach(node => {
    if (node.parentId === null) {
      const rootNode = nodeMap.get(node.id)!;
      rootNode.children = buildTree(nodeMap, node.id);
      roots.push(rootNode);
    }
  });
  return roots;
}

// 示例用法
const items: TreeNode[] = [
  { id: 1, name: 'Node 1', parentId: null },
  { id: 2, name: 'Node 1.1', parentId: 1 },
  { id: 3, name: 'Node 1.2', parentId: 1 },
  { id: 4, name: 'Node 1.1.1', parentId: 2 },
  { id: 5, name: 'Node 1.1.2', parentId: 2 },
  { id: 6, name: 'Node 1.2.1', parentId: 3 },
  { id: 7, name: 'Node 2', parentId: null },
  { id: 8, name: 'Node 2.1', parentId: 7 },
];

const tree = arrayToTree(items);
console.log(JSON.stringify(tree, null, 2));