JavaScript实现无限级递归树的示例代码


Posted in Javascript onMarch 29, 2019

需求

最近遇到一个需求,平时被后台惯着直接返回了树形结构给到前端,前端对这种嵌套类型的数据(如地区的级联或菜单的树形结构)省掉了一层处理。换了个后台开发返回了扁平化的数组数据给到前端自己去处理如下data。突然有点慌......

const data = [
  {
    "area_id": 5,
    "name": "广东省",
    "parent_id": 0,
  }, 
  {
    "area_id": 6,
    "name": "广州市",
    "parent_id": 5,
  },
  {
    "area_id": 7,
    "name": "深圳市",
    "parent_id": 5,
  },
  {
    "area_id": 4,
    "name": "北京市",
    "parent_id": 3,
  },
  {
    "area_id": 3,
    "name": "北京",
    "parent_id": 0,
  },
  {
    "area_id": 2,
    "name": "测试子地区",
    "parent_id": 1,
  },
  {
    "area_id": 1,
    "name": "测试地区",
    "parent_id": 0,
  }
]

JavaScript实现无限级递归树的示例代码

emmm,换个念头想想也刚好锻炼锻炼,撸起袖子干吧,然后就总结了以下两种整理方法~

方法一——递归

在这种那么适合递归的场景,怎么能少了递归这个角色呢?第一种方法,递归出场!献上递归宝器~

function toTreeData(data,pid){
 
  function tree(id) {
    let arr = []
    data.filter(item => {
      return item.parent_id === id;
    }).forEach(item => {
      arr.push({
        area_id: item.area_id,
        label: item.name,
        children: tree(item.area_id)
      })
    })
    return arr
  }
  return tree(pid) // 第一级节点的父id,是null或者0,视情况传入
}

恩,姿势摆好,在控制台里执行一下

JavaScript实现无限级递归树的示例代码

哎哟,不错哦~后台小哥哥再也不担心需要返回什么数据给我了。不过,该方法有个缺点,在我使用组件的时候需要的数据结构中,如果子级没有数据children返回[]。恩,有点问题,但是还是可以优化的,优化的代码我会那么容易给出来吗?你已经是个成熟的程序猿了,需要学会自己优化代码了!!!

方法二——对象

对象在我眼里一直是倚天屠龙宝刀的存在,了解到其中的奥妙便形同有一武林秘籍傍身。当然,没用好就相当于一堆废铁,甚至将导致一些不可预料的结果。

function setTreeData(arr) {
  // 删除所有 children,以防止多次调用
  arr.forEach(function (item) {
      delete item.children;
  });
  let map = {}; // 构建map
  arr.forEach(i => {
    map[i.area_id] = i; // 构建以area_id为键 当前数据为值
  });

  let treeData = [];
  arr.forEach(child => {
    const mapItem = map[child.parent_id]; // 判断当前数据的parent_id是否存在map中

    if (mapItem) { // 存在则表示当前数据不是最顶层数据
    
      // 注意: 这里的map中的数据是引用了arr的它的指向还是arr,当mapItem改变时arr也会改变,踩坑点
      (mapItem.children || ( mapItem.children = [] )).push(child); // 这里判断mapItem中是否存在children, 存在则插入当前数据, 不存在则赋值children为[]然后再插入当前数据
    } else { // 不存在则是组顶层数据
      treeData.push(child);
    }
  });

  return treeData;
};

console.log(setTreeData(data)); // 输出整理后的数据

结果我就不执行了,跟递归的结果相似。相比起递归,我更喜欢这种方法。不过这种方法有一种容易犯错的地方,就是它会改变原数据,我就在这里踩了好久的坑,所以一开始采用了删除children的初始化了一遍。 记住了吗,没记住自行重复说三遍!!!

总结

以上简单介绍了两种将扁平化数据转化为递归树的方法,学会了吗,没学会再回去好好撸撸码!!目前我遇到需要将数据整理树形结构的主要在菜单栏或分类的树形结构上,当然还有像省市这种有从属关系的结构。不过就算以后遇到了都唔驶惊啦~恩,继续更新总结中....

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在网页中控制wmplayer播放器
Jul 01 Javascript
Javascript的getYear、getFullYear、getUTCFullYear异同分享
Nov 30 Javascript
关于img的href和src取变量及赋值的方法
Apr 28 Javascript
纯javascript实现分页(两种方法)
Aug 26 Javascript
JavaScript中实现Map的示例代码
Sep 09 Javascript
JS日期格式化之javascript Date format
Oct 01 Javascript
轻松搞定jQuery.noConflict()
Feb 15 Javascript
jQuery中each()、find()和filter()等节点操作方法详解(推荐)
May 25 Javascript
基于vue2.0+vuex的日期选择组件功能实现
Mar 13 Javascript
微信小程序 支付功能(前端)的实现
May 24 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
Sep 30 Javascript
vue 设置 input 为不可以编辑的实现方法
Sep 19 Javascript
使用weixin-java-miniapp配置进行单个小程序的配置详解
Mar 29 #Javascript
详解a标签添加onclick事件的几种方式
Mar 29 #Javascript
node(koa2) web应用模块介绍详解
Mar 29 #Javascript
Vue js 的生命周期(看了就懂)(推荐)
Mar 29 #Javascript
浅谈js闭包理解
Mar 28 #Javascript
微信小程序中转义字符的处理方法
Mar 28 #Javascript
微信小程序中使用Async-await方法异步请求变为同步请求方法
Mar 28 #Javascript
You might like
自动跳转中英文页面
2006/10/09 PHP
PHP3 safe_mode 失效漏洞
2006/10/09 PHP
PHP将两个关联数组合并函数提高函数效率
2014/03/18 PHP
php内存缓存实现方法
2015/01/24 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
Thinkphp 框架配置操作之动态配置、扩展配置及批量配置实例分析
2020/05/15 PHP
Extjs Gird 支持中文拼音排序实现代码
2013/04/15 Javascript
jquery scroll()区分横向纵向滚动条的方法
2014/04/04 Javascript
基于jquery实现图片上传本地预览功能
2016/01/08 Javascript
JavaScript函数中关于valueOf和toString的理解
2016/06/14 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
Angular.JS判断复选框checkbox是否选中并实时显示
2016/11/30 Javascript
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
微信小程序开发之麦克风动画 帧动画 放大 淡出
2017/04/18 Javascript
微信小程序之页面拦截器的示例代码
2017/09/07 Javascript
jquery动态添加以及遍历option并获取特定样式名称的option方法
2018/01/29 jQuery
Node.js readline模块与util模块的使用
2018/03/01 Javascript
JS使用遮罩实现点击某区域以外时弹窗的弹出与关闭功能示例
2018/07/31 Javascript
Echarts之悬浮框中的数据排序问题
2018/11/08 Javascript
layui自定义ajax左侧三级菜单
2019/07/26 Javascript
微信小程序分包加载代码实现方法详解
2019/09/23 Javascript
在vue中利用v-html按分号将文本换行的例子
2019/11/14 Javascript
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
html5使用canvas画三角形
2014/12/15 HTML / CSS
理肤泉俄罗斯官网:La Roche-Posay俄罗斯
2018/07/24 全球购物
Silk Therapeutics官网:清洁、抗衰老护肤品
2020/08/12 全球购物
科颜氏香港官方网店:Kiehl’s香港
2021/03/07 全球购物
如何判断一段程序是由C 编译程序还是由C++编译程序编译的
2013/08/04 面试题
公务员政审个人鉴定
2014/02/25 职场文书
项目委托协议书(最新)
2014/09/13 职场文书
办公室文员工作自我鉴定
2014/09/19 职场文书
销售经理岗位职责
2015/01/31 职场文书
财务部岗位职责
2015/02/03 职场文书
中班教师个人总结
2015/02/05 职场文书
班干部学习委员竞选稿
2015/11/20 职场文书