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 相关文章推荐
关于图片按比例自适应缩放的js代码
Oct 30 Javascript
js修改input的type属性问题探讨
Oct 12 Javascript
使用jQuery制作浮动工具栏的实例分享
May 13 Javascript
实例讲解JavaScript中的this指向错误解决方法
Jun 13 Javascript
JS沙箱模式实例分析
Sep 04 Javascript
AngularJS实现的锚点楼层跳转功能示例
Jan 02 Javascript
小程序实现多列选择器
Feb 15 Javascript
深入理解vue-class-component源码阅读
Feb 18 Javascript
详解关于html,css,js三者的加载顺序问题
Apr 10 Javascript
JS前端知识点offset,scroll,client,冒泡,事件对象的应用整理总结
Jun 27 Javascript
对layui初始化列表的CheckBox属性详解
Sep 13 Javascript
electron踩坑之dialog中的callback解决
Oct 06 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
德生PL990的分析评价
2021/03/02 无线电
浅析php fwrite写入txt文件的时候用 \r\n不能换行的问题
2013/08/06 PHP
php实现的IMEI限制的短信验证码发送类
2015/05/05 PHP
PHP中new static()与new self()的比较
2016/08/19 PHP
CI框架实现框架前后端分离的方法详解
2016/12/30 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
2019/11/26 PHP
加载 Javascript 最佳实践
2011/10/30 Javascript
jquery ajax post提交数据乱码
2013/11/05 Javascript
jQuery封装的tab选项卡插件分享
2015/06/16 Javascript
再谈JavaScript线程
2015/07/10 Javascript
js实现Select列表各项上移和下移的方法
2015/08/14 Javascript
ReactJs快速入门教程(精华版)
2016/11/28 Javascript
vue组件学习教程
2017/09/09 Javascript
详解webpack-dev-server使用http-proxy解决跨域问题
2018/01/13 Javascript
vue进行图片的预加载watch用法实例讲解
2018/02/07 Javascript
原生JS实现的碰撞检测功能示例
2018/05/18 Javascript
vue 自定义指令自动获取文本框焦点的方法
2018/08/25 Javascript
element ui分页多选,翻页记忆的实例
2019/09/03 Javascript
基于Vue全局组件与局部组件的区别说明
2020/08/11 Javascript
python两种遍历字典(dict)的方法比较
2014/05/29 Python
Python Tkinter基础控件用法
2014/09/03 Python
python下paramiko模块实现ssh连接登录Linux服务器
2015/06/03 Python
Python基于列表模拟堆栈和队列功能示例
2018/01/05 Python
解决安装pycharm后不能执行python脚本的问题
2019/01/19 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
2019/09/20 Python
在使用非全零作为空指针内部表达的机器上, NULL是如何定义
2014/11/09 面试题
土木工程专业大学毕业生求职信
2013/10/13 职场文书
顶撞领导检讨书
2014/01/29 职场文书
社区母亲节活动记录
2014/03/06 职场文书
弘扬民族精神演讲稿
2014/05/07 职场文书
机械设计制造及其自动化专业求职信
2014/06/17 职场文书
店铺转让协议书(2014版)
2014/09/23 职场文书
转让协议书
2015/01/27 职场文书
明星邀请函
2015/02/02 职场文书
建党伟业的观后感
2015/06/01 职场文书
Python实现照片卡通化
2021/12/06 Python