# 数组转树形结构

数组数据示例如下:

const data  = [
    { id: 1, pid: 0, name: "上海市" },
    { id: 2, pid: 1, name: "杨浦区" },
    { id: 3, pid: 1, name: "静安区" },
    { id: 4, pid: 2, name: "营口路" },
    { id: 5, pid: 3, name: "北京西路" },
    { id: 6, pid: 2, name: "长海路" },
    { id: 7, pid: 3, name: "长寿路" },
    { id: 8, pid: 4, name: "1号楼" },
    { id: 9, pid: 4, name: "2号楼" },
]

期望结构

[
  {
    id: 1,
    pid: 0,
    name: "上海市",
    children: [
      {
        id: 2,
        pid: 1,
        name: "杨浦区",
        children: [
          {
            id: 4,
            pid: 2,
            name: "营口路",
            children: [
              {
                id: 8,
                pid: 4,
                name: "1号楼",
                children: [],
              },
              {
                id: 9,
                pid: 4,
                name: "2号楼",
                children: [],
              },
            ],
          },
          {
            id: 6,
            pid: 2,
            name: "长海路",
            children: [],
          },
        ],
      },
      {
        id: 3,
        pid: 1,
        name: "静安区",
        children: [
          {
            id: 5,
            pid: 3,
            name: "北京西路",
            children: [],
          },
          {
            id: 7,
            pid: 3,
            name: "长寿路",
            children: [],
          },
        ],
      },
    ],
  },
];

# 使用递归方法

const getChildren = (data, result, pid) => {
  data.forEach((item) => {
    if (item.pid === pid) {
      let newItem = { ...item, children: [] };
      result.push(newItem);
      getChildren(data, newItem.children, newItem.id);
    }
  });
};

const genTreeDataByArray = (data, pid = 0) => {
  const result = [];
  getChildren(data, result, pid);
  return result;
};

# 不使用递归方法

const genTreeData = (data) => {
  let res = [];
  if (!Array.isArray(data)) {
    return res;
  }

  // 将数组转换成对象(键值对),将ID作为属性名,原来的数组里的对象作为属性值
  let obj = {};
  data.forEach((item) => {
    obj[item.id] = item;
  });

  // 通过对象的属性名(ID)来找到父级节点,将存到map里的对象取出来放到父级节点的childere数组中

  data.forEach((item) => {
    let parent = obj[item.pid];

    delete item.pid;
    item["label"] = item.name;
    delete item.name;

    if (parent) {
      parent.children = parent.children ? parent.children : [];
      parent.children.push(item);
    } else {
      res.push(item);
    }
  });
  return res;
};
Last Updated: 2/14/2023, 11:03:39 PM