前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >js将列表组装成树结构的两种方式

js将列表组装成树结构的两种方式

作者头像
用户6256742
发布2024-06-30 09:34:03
980
发布2024-06-30 09:34:03
举报
文章被收录于专栏:网络日志网络日志

工作中偶尔就会遇到后端同学丢来一个列表,要我们自己组装成一个树结构渲染到页面上,本文以两种不同方式探索生成树的算法思想。

js将列表组装成树结构的两种方式
js将列表组装成树结构的两种方式

背景介绍

可组装成树结构的数组一般有以下几个要素:

  • id 当前节点id
  • parentId 当前节点的父节点id
  • children 子节点列表(可能不会在接口中返回,需要组装时候自己加上)

原始结构:

js将列表组装成树结构的两种方式
js将列表组装成树结构的两种方式

目标结构:

js将列表组装成树结构的两种方式
js将列表组装成树结构的两种方式

关键就是一维数组中通过parentId找到其对应的父节点并添加到父节点的children数组中。

实现方案

最直接的方式就是遍历数组,并把找到的子节点逐一添加到父节点中

代码语言:javascript
复制
function listToTreeSimple(data) {
  const res = [];
  data.forEach((item) => {
    const parent = data.find((node) => node.id === item.parentId);
    if (parent) {
      parent.children = parent.children || [];
      parent.children.push(item);
    } else {
      // * 根节点
      res.push(item);
    }
  });
  return res;
}

考虑进一步优化,使用哈希表,以id为key存储每个节点值,省去data.find计算

代码语言:javascript
复制
function listToTree(data) {
  // * 先生成parent建立父子关系
  const obj = {};
  data.forEach((item) => {
    obj[item.id] = item;
  });
  // * obj -> {1001: {id: 1001, parentId: 0, name: 'AA'}, 1002: {...}}
  // console.log(obj, "obj")
  const parentList = [];
  data.forEach((item) => {
    const parent = obj[item.parentId];
    if (parent) {
      // * 当前项有父节点
      parent.children = parent.children || [];
      parent.children.push(item);
    } else {
      // * 当前项没有父节点 -> 顶层
      parentList.push(item);
    }
  });
  return parentList;
}

即便数据量很小,带来的性能提升也是显著的

js将列表组装成树结构的两种方式
js将列表组装成树结构的两种方式

递归法

更有骚操作递归法,性能会很差,但代码会很酷😎

代码语言:javascript
复制
function recursiveToTree(data) {
  function loop(key) {
    const arr = [];
    data.forEach((item) => {
      if (item.parentId === key) {
        item.children = loop(item.id);
        arr.push(item);
      }
    });
    return res;
  }
  return loop(1);
}

看看性能,诶?看起来竟然递归性能最佳🤔

js将列表组装成树结构的两种方式
js将列表组装成树结构的两种方式

但是数据量稍微大一点……

js将列表组装成树结构的两种方式
js将列表组装成树结构的两种方式

(上面递归,下面非递归)

资源

原始数据列表

代码语言:javascript
复制
const list = [
  {
    id: 1001,
    parentId: 0,
    name: "AA",
  },
  {
    id: 1002,
    parentId: 1001,
    name: "BB",
  },
  {
    id: 1003,
    parentId: 1001,
    name: "CC",
  },
  {
    id: 1004,
    parentId: 1003,
    name: "DD",
  },
  {
    id: 1005,
    parentId: 1003,
    name: "EE",
  },
  {
    id: 1006,
    parentId: 1002,
    name: "FF",
  },
  {
    id: 1007,
    parentId: 1002,
    name: "GG",
  },
  {
    id: 1008,
    parentId: 1004,
    name: "HH",
  },
  {
    id: 1009,
    parentId: 1005,
    name: "II",
  },
];
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍
  • 实现方案
  • 递归法
  • 资源
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档