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 相关文章推荐
基于jQuery架构javascript基础体系
Jan 01 Javascript
node.js中的path.dirname方法使用说明
Dec 09 Javascript
解析JavaScript的ES6版本中的解构赋值
Jul 28 Javascript
JS实现仿腾讯微博无刷新删除微博效果代码
Oct 16 Javascript
Js+Ajax,Get和Post在使用上的区别小结
Jun 08 Javascript
jQuery实现的自定义弹出层效果实例详解
Sep 04 Javascript
Vue.js框架路由使用方法实例详解
Aug 25 Javascript
在原生不支持的旧环境中添加兼容的Object.keys实现方法
Sep 11 Javascript
vue router 通过路由来实现切换头部标题功能
Apr 24 Javascript
详解小程序input框失焦事件在提交事件前的处理
May 05 Javascript
vue相同路由跳转强制刷新该路由组件操作
Aug 05 Javascript
vue2的 router在使用过程中遇到的一些问题
Apr 13 Vue.js
使用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和ACCESS写聊天室(一)
2006/10/09 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
PHP-FPM之Chroot执行环境详解
2015/08/03 PHP
phplist及phpmailer(组合使用)通过gmail发送邮件的配置方法
2016/03/30 PHP
php中10个不同等级压缩优化图片操作示例
2016/11/14 PHP
php array_map()函数实例用法
2021/03/03 PHP
jQuery选择没有colspan属性的td的代码
2010/07/06 Javascript
javascript判断chrome浏览器的方法
2014/03/26 Javascript
jQuery 写的简单打字游戏可以提示正确和错误的次数
2014/07/01 Javascript
jQuery中even选择器的定义和用法
2014/12/23 Javascript
简单谈谈node.js 版本控制 nvm和 n
2015/10/15 Javascript
深入解析JavaScript框架Backbone.js中的事件机制
2016/02/14 Javascript
理解javascript函数式编程中的闭包(closure)
2016/03/08 Javascript
node.js缺少mysql模块运行报错的解决方法
2016/11/13 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
2016/11/16 Javascript
基于Particles.js制作超炫粒子动态背景效果(仿知乎)
2017/09/13 Javascript
Mac中安装nvm的教程分享
2017/12/11 Javascript
Vue组件的使用及个人理解与介绍
2019/02/09 Javascript
微信小程序实现左右列表联动
2020/05/19 Javascript
利用Python暴力破解zip文件口令的方法详解
2017/12/21 Python
Python查找第n个子串的技巧分享
2018/06/27 Python
基于python实现自动化办公学习笔记(CSV、word、Excel、PPT)
2019/08/06 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
2020/03/01 Python
python使用正则表达式匹配txt特定字符串(有换行)
2020/12/09 Python
iPhoneX安全区域(Safe Area)底部小黑条在微信小程序和H5的屏幕适配
2020/04/08 HTML / CSS
单位未婚证明范本
2014/01/18 职场文书
知识竞赛主持词
2014/03/26 职场文书
物理学专业自荐信
2014/06/11 职场文书
小区环境卫生倡议书
2015/04/29 职场文书
代理词怎么写
2015/05/25 职场文书
公司保洁员管理制度
2015/08/04 职场文书
单位车辆管理制度
2015/08/05 职场文书
军训后的感想
2015/08/07 职场文书
2019生态环境保护倡议书!
2019/07/03 职场文书
导游词之西江千户苗寨
2019/12/24 职场文书
mysql中varchar类型的日期进行比较、排序等操作的实现
2021/11/17 MySQL