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实现页面打印功能实例代码(附去页眉页脚功能代码)
Dec 15 Javascript
jquery $.ajax()取xml数据的小问题解决方法
Nov 20 Javascript
火狐textarea输入法的bug的触发及解决
Jul 24 Javascript
JS实现图片横向滚动效果示例代码
Sep 04 Javascript
js动态添加事件并可传参数示例代码
Oct 21 Javascript
Vue.js每天必学之计算属性computed与$watch
Sep 05 Javascript
JavaScript基于自定义函数判断变量类型的实现方法
Nov 23 Javascript
js实现截图保存图片功能的代码示例
Feb 16 Javascript
JavaScript 总结几个提高性能知识点(推荐)
Feb 20 Javascript
Javascript中的async awai的用法
May 17 Javascript
很棒的vue弹窗组件
May 24 Javascript
写一个Vue loading 插件
Nov 09 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
PHP 简单数组排序实现代码
2009/08/05 PHP
PHP获取POST数据的几种方法汇总
2015/03/03 PHP
JavaScript读取中文cookie时的乱码问题的解决方法
2009/10/14 Javascript
javascript中自定义对象的属性方法分享
2013/07/12 Javascript
Javascript仿新浪游戏频道鼠标悬停显示子菜单效果
2015/08/21 Javascript
Three.js基础部分学习
2017/01/08 Javascript
php输出全部gb2312编码内的汉字方法
2017/03/04 Javascript
jQuery实现获取h1-h6标题元素值的方法
2017/03/06 Javascript
基于bootstrap实现收缩导航条
2017/03/17 Javascript
AngularJS1.X学习笔记2-数据绑定详解
2017/04/01 Javascript
深入理解react-router@4.0 使用和源码解析
2017/05/23 Javascript
vue.js声明式渲染和条件与循环基础知识
2017/07/31 Javascript
Vue自定义指令上报Google Analytics事件统计的方法
2019/02/25 Javascript
vue中配置scss全局变量的步骤
2020/12/28 Vue.js
Vue项目打包部署到apache服务器的方法步骤
2021/02/01 Vue.js
Python多线程编程简单介绍
2015/04/13 Python
python比较2个xml内容的方法
2015/05/11 Python
Python实现简单的文件传输与MySQL备份的脚本分享
2016/01/03 Python
Python 字符串与数字输出方法
2018/07/16 Python
树莓派极简安装OpenCv的方法步骤
2019/10/10 Python
新手入门学习python Numpy基础操作
2020/03/02 Python
Django Form设置文本框为readonly操作
2020/07/03 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
html5触摸事件判断滑动方向的实现
2018/06/05 HTML / CSS
Roxy荷兰官方网站:冲浪、滑雪板、服装和配件
2019/10/22 全球购物
锐步英国官网:Reebok英国
2019/11/29 全球购物
JSF如何进行表格处理及取值
2012/08/06 面试题
几个常见的软件测试问题
2016/09/07 面试题
幼师自荐信
2013/10/26 职场文书
电气工程和自动化自荐信范文
2013/12/25 职场文书
教育学习自我评价
2014/02/03 职场文书
会计人员岗位职责
2014/03/19 职场文书
《分一分》教学反思
2014/04/13 职场文书
给老婆的检讨书(搞笑版)
2015/05/06 职场文书
2015年图书馆个人工作总结
2015/05/26 职场文书
Python学习开发之图形用户界面详解
2021/08/23 Python