「functions」为树节点添加路径

65 阅读1分钟

需求点:原始数据为平铺的树节点,通过 pid 属性关联父节点;需要将当前节点的所有父辈节点以及自身节点的 id 构造成节点的路径

代码实现

type TreeNode = {
  id: string
  pid: string
  paths?: string[]
}

function setNodePaths(data: TreeNode[]): TreeNode[] {
  // 创建副本
  const nodes: TreeNode[] = JSON.parse(JSON.stringify(data))

  // 创建映射
  const nodeMap = new Map<string, TreeNode>()
  nodes.forEach((node) => nodeMap.set(node.id, node))

  function findPaths(id: string): string[] {
    const node = nodeMap.get(id)
    if (!node) return []
    if (node.paths && node.paths.length > 0) return node.paths

    // 先从父节点获取 paths
    const parentPaths = findPaths(node.pid)
    node.paths = [...parentPaths, node.id]
    return node.paths
  }

  nodes.forEach((node) => findPaths(node.id))
  return nodes
}
const data: TreeNode[] = [
  { id: '1-1-1', pid: '1-1' },
  { id: '1-1-2', pid: '1-1' },
  { id: '1', pid: '0' },
  { id: '1-1', pid: '1' },
  { id: '1-2', pid: '1' },
]

console.log(setNodePaths(data))

// [
//   { id: '1-1-1', pid: '1-1', paths: ['1', '1-1', '1-1-1'] },
//   { id: '1-1-2', pid: '1-1', paths: ['1', '1-1', '1-1-2'] },
//   { id: '1', pid: '0', paths: ['1'] },
//   { id: '1-1', pid: '1', paths: ['1', '1-1'] },
//   { id: '1-2', pid: '1', paths: ['1', '1-2'] },
// ]