列表转树形

60 阅读1分钟

把这样的数据结构转成一个属性

let arr = [
    { id: 1, name: '部门1', pid: 0 },
    { id: 2, name: '部门2', pid: 1 },
    { id: 3, name: '部门3', pid: 1 },
    { id: 4, name: '部门4', pid: 3 },
    { id: 5, name: '部门5', pid: 4 },
    { id: 6, name: '部门6', pid: 0 },
]

思路

怎么加入到父节点的 children 中

  • 维护一个 id 和 children 的哈希表,遍历每个节点的时候,可以直接通过 pid 获取到父元素的 children,直接加入即可

何时给原元素加上 children 属性?

  • 在遍历的过程中直接从哈希表获取。
  • 我们从哈希表获取当前元素的 children,
  • 如果获取不到则初始化并且加入到 hash 里面

可以不初始化 children 属性吗?

  • 因为在顺序遍历一个无序数组的过程中无法确定某个节点是否有子元素,所以默认都加一个 children 属性。否则 hash 表里的 children 和实际元素的 children 是无法同步的

代码

const id2children = {};
const tree: any[] = [];
const list2tree = (list: any[]) => {
  for (let i = 0; i < list.length; i++) {
    const item = list[i];
    item.children = id2children[item.id]
      ? id2children[item.id]
      : (id2children[item.id] = []);
    if (item.pid === 0 || item.pid === undefined) {
      tree.push(item);
    } else {
      if (id2children[item.pid]) {
        id2children[item.pid].push(item);
      } else {
        id2children[item.pid] = [item];
      }
    }
  }
  return tree;
};