前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >不用递归生成无限层级的树

不用递归生成无限层级的树

作者头像
同学小强
发布2022-08-24 14:47:10
1K0
发布2022-08-24 14:47:10
举报
文章被收录于专栏:同学小强

偶然间,在技术群里聊到生成无限层级树的老话题,故此记录下,n年前一次生成无限层级树的解决方案

业务场景

处理国家行政区域的树,省市区,最小颗粒到医院,后端回包平铺数据大小1M多,前端处理数据后再渲染,卡顿明显

后端返回的数据结构

代码语言:javascript
复制
[
    {
      "id": 1,
      "name": "中华人民共和国",
      "parentId": 0,
    },
    {
      "id": 1001,
      "name": "浙江省",
      "parentId": 1,
    },
    {
      "id": 2001,
      "name": "杭州市",
      "parentId": 1001,
    },
    {
      "id": 3001,
      "name": "西湖区",
      "parentId": 2001,
    },
    {
      "id": 4001,
      "name": "杭州市第一人民医院",
      "parentId": 3001,
    },
    // 其他略
]
代码语言:javascript
复制

第一版:递归处理树

常规处理方式

代码语言:javascript
复制
// 略,网上一抓一把

第二版:非递归处理树

改进版处理方式

代码语言:javascript
复制
const buildTree = (itemArray, { id = 'id', parentId = 'parentId', children = 'children', topLevelId = '0' } = {}) => {
  return itemArray.filter((item) => {
    // 挂载子级
    item[children] = itemArray.filter((child) => String(item[id]) === String(child[parentId]));
    // 返回顶层数据
    return String(item[parentId]) === topLevelId;
  });
};

时间复杂度:O(n^2)

第三版:非递归处理树

代码语言:javascript
复制
import { groupBy } from 'lodash';

const buildTree = (itemArray, { id = 'id', parentId = 'parentId', children = 'children', topLevelId = '0' } = {}) => {
  const parentObj = groupBy(itemArray, parentId)
  return itemArray.filter((item) => {
    // 挂载子级
    item[children] = parentObj[item[id]];
    // 返回顶层数据
    return String(item[parentId]) === topLevelId;
  });
};

时间复杂度:O(2n)

最终版:非递归处理树

代码语言:javascript
复制
const buildTree = (itemArray, { id = 'id', parentId = 'parentId', children = 'children', topLevelId = '0' } = {}) => {
  const parentMap = new Map(); // 临时存储所有父级
  const topLevelResult = [];   // 存储顶层结果
  for(let item of itemArray) {
    if(!parentMap.has(item[id])) {
      item[children] = []
    } else {
      item[children] = parentMap.get(item[id])[children];
    }

    parentMap.set(item.id, item)

    if(!parentMap.has(item[parentId])) {
      parentMap.set(item[parentId], {
        [children]: []
      });
    }
    parentMap.get(item[parentId])[children].push(item)
    if (String(item[parentId]) === String(topLevelId)) {
      topLevelResult.push(item)
    }
  }
  return topLevelResult;
}

时间复杂度:O(n)

x下篇分享不用递归无限层级树取交集

END

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 同学小强 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 业务场景
  • 后端返回的数据结构
  • 第一版:递归处理树
  • 第二版:非递归处理树
  • 第三版:非递归处理树
  • 最终版:非递归处理树
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档