树形结构与扁平结构转换

Daotin 于 2022-11-02 发布 编辑

参考文档:https://juejin.cn/post/6987224048564437029

扁平化数组转换成树形结构

/**
 * 将扁平化数组转换成树形结构
 */

let arr = [
  { id: 1, pid: 0, text: "111" },
  { id: 2, pid: 1, text: "222" },
  { id: 3, pid: 1, text: "333" },
  { id: 4, pid: 3, text: "444" },
  { id: 5, pid: 0, text: "555" },
];

// 1、for循环方式1
// function arr2Tree(arr, pid) {
//   function loop(pid) {
//     let res = [];
//     for (const item of arr) {
//       if (item.pid !== pid) {
//         continue;
//       }
//       item.children = loop(item.id);
//       res.push(item);
//     }
//     return res;
//   }

//   return loop(pid);
// }

// 1、for循环方式2
// function arr2Tree(arr, pid) {
//   let res = [];
//   function loop(pid, res) {
//     for (const item of arr) {
//       if (item.pid === pid) {
//         const newItem = { ...item, children: [] };
//         res.push(newItem);
//         loop(item.id, newItem.children);
//       }
//     }
//   }
//   loop(pid, res);
//   return res;
// }

// 2、reduce方式
// function arr2Tree(arr, pid) {
//   function loop(pid) {
//     return arr.reduce((res, item) => {
//       if (item.pid === pid) {
//         item.children = loop(item.id);
//         res.push(item);
//       }
//       return res;
//     }, []);
//   }

//   return loop(pid);
// }

// 使用map索引(2次遍历)
// function arr2Tree(arr, pid) {
//   let res = [];
//   let map = {};
//   arr.forEach((item) => {
//     map[item.id] = item;
//   });

//   arr.forEach((item) => {
//     let itemTmp = map[item.pid];
//     if (itemTmp) {
//       itemTmp.children
//         ? itemTmp.children.push(item)
//         : (itemTmp.children = [item]);
//     } else {
//       res.push(item);
//     }
//   });

//   return res;
// }

// map索引(1次遍历)
function arr2Tree(arr, root) {
  const result = []; // 用于存放结果
  const map = {}; // 用于存放 arr 下的节点

  // 遍历 arr
  for (const item of arr) {
    // 1. 获取节点的 id 和 父 id
    const { id, pid } = item; // ES6 解构赋值

    // 2. 将节点存入 map
    if (!map[id]) {
      map[id] = {};
    }

    // 3. 根据 id,将节点与之前存入的子节点合并
    map[id] = map[id].children
      ? { ...item, children: map[id].children }
      : { ...item };

    // 4. 如果是根节点,存入 result
    if (pid === root) {
      result.push(map[id]);
    } else {
      // 5. 反之,存入父节点
      if (!map[pid]) map[pid] = {};
      if (!map[pid].children) map[pid].children = [];
      map[pid].children.push(map[id]);
    }
  }

  // 将结果返回
  return result;
}

let tree = arr2Tree(arr, 0);

console.log("⭐arr2Tree==>", tree);

树形结构扁平化

/**
 * 树形结构扁平化
 */

// 1、for循环遍历
// function tree2Arr(tree) {
//   let res = [];
//   tree.forEach((treeItem) => {
//     let { children, ...params } = treeItem;
//     res.push(params);
//     if (children?.length) {
//       res = res.concat(tree2Arr(children));
//     }
//   });

//   return res;
// }

// 2、使用reduce
// function tree2Arr(tree) {
//   return tree.reduce((res, treeItem) => {
//     let { children, ...params } = treeItem;

//     res.push(params);
//     if (children?.length) {
//       res = res.concat(tree2Arr(children));
//     }
//     return res;
//   }, []);
// }

console.log("⭐tree2Arr==>", tree2Arr(tree));

// 参考文档:https://juejin.cn/post/6987224048564437029