js 将线性数据转为树形的示例代码


Posted in Javascript onMay 28, 2019

在日常开发工作中,我们经常碰到将线性的数据转换成树的需求,今天给大家分享一个简单的转换算法。

数据结构

下面是我们转换前的数据:

[
  {
    "id":1,
    "parent_id":0,
    "name":"四川省"
  },
  {
    "id":2,
    "parent_id":0,
    "name":"广东省"
  },
  {
    "id":3,
    "parent_id":0,
    "name":"江西省"
  },
  {
    "id":5,
    "parent_id":1,
    "name":"成都市"
  },
  {
    "id":6,
    "parent_id":5,
    "name":"锦江区"
  },
  {
    "id":7,
    "parent_id":6,
    "name":"九眼桥"
  },
  {
    "id":8,
    "parent_id":6,
    "name":"兰桂坊"
  },
  {
    "id":9,
    "parent_id":2,
    "name":"东莞市"
  },
  {
    "id":10,
    "parent_id":9,
    "name":"长安镇"
  },
  {
    "id":11,
    "parent_id":3,
    "name":"南昌市"
  }
]

我们转换后的结果是:

[
  {
    "id":1,
    "parent_id":0,
    "name":"四川省",
    "children":[
      {
        "id":5,
        "parent_id":1,
        "name":"成都市",
        "children":[
          {
            "id":6,
            "parent_id":5,
            "name":"锦江区",
            "children":[
              {
                "id":7,
                "parent_id":6,
                "name":"九眼桥"
              },
              {
                "id":8,
                "parent_id":6,
                "name":"兰桂坊"
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "id":2,
    "parent_id":0,
    "name":"广东省",
    "children":[
      {
        "id":9,
        "parent_id":2,
        "name":"东莞市",
        "children":[
          {
            "id":10,
            "parent_id":9,
            "name":"长安镇"
          }
        ]
      }
    ]
  },
  {
    "id":3,
    "parent_id":0,
    "name":"江西省",
    "children":[
      {
        "id":11,
        "parent_id":3,
        "name":"南昌市"
      }
    ]
  }
]

实现代码

let array = [
  {
    id: 1,
    parent_id: 0,
    name: "四川省"
  },
  {
    id: 2,
    parent_id: 0,
    name: "广东省"
  },
  {
    id: 3,
    parent_id: 0,
    name: "江西省"
  },
  {
    id: 5,
    parent_id: 1,
    name: "成都市"
  },
  {
    id: 6,
    parent_id: 5,
    name: "锦江区"
  },
  {
    id: 7,
    parent_id: 6,
    name: "九眼桥"
  },
  {
    id: 8,
    parent_id: 6,
    name: "兰桂坊"
  },
  {
    id: 9,
    parent_id: 2,
    name: "东莞市"
  },
  {
    id: 10,
    parent_id: 9,
    name: "长安镇"
  },
  {
    id: 11,
    parent_id: 3,
    name: "南昌市"
  }
]

function listToTree(list) {
  let map = {};
  list.forEach(item => {
    if (! map[item.id]) {
      map[item.id] = item;
    }
  });

  list.forEach(item => {
    if (item.parent_id !== 0) {
      map[item.parent_id].children ? map[item.parent_id].children.push(item) : map[item.parent_id].children = [item];
    }
  });
  
  return list.filter(item => {
    if (item.parent_id === 0) {
      return item;
    }
  })
}
console.log(listToTree(array));

分析

这段代码的核心就在 listToTree 方法中,这个方法分为了三个部分:

第一部分

第一部分先将数组中的所有元素都复制到 map 中(注意:这里是引用复制哦,这个细节很重要)。

第二部分

执行第二次遍历前的 map:

// map
{
 ...,
 "3":{
    "id":3,
    "parent_id":0,
    "name":"江西省"
  },
  ...
}

然后这个时候遍历 parent_id 不等于 0 的元素:

[
 ...,
 {
 id: 11,
 parent_id: 3,
 name: "南昌市"
 },
  ...
]

然后发现南昌市有 parent_id,我们再给 map[item.parent_id] 设置子元素,通过南昌市的 parent_id 可以推导出:

map["3"].children ? map["3"].children.push(item) : map[3].children = [item];

上面的代码判断了是否存在 children,如果不存在则直接给它赋值,否则将值 push 到 children 中。

执行完第二步后,我们已经把子节点添加到了它的父节点上,但是我们并没有删除掉之前的子节点。所以第三部就是对数据进行过滤,只要父节点即可。

js 将线性数据转为树形的示例代码

总结

需要注意的是,我们一直都是对 map 进行操作的,但是结果怎么到了 list 上呢,这就是上面提到的引用复制。

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

Javascript 相关文章推荐
ExtJS Store的数据访问与更新问题
Apr 28 Javascript
关于递归运算的顺序测试代码
Nov 30 Javascript
qq悬浮代码(兼容各个浏览器)
Jan 29 Javascript
js改变鼠标的形状和样式的方法
Mar 31 Javascript
jQuery实现响应鼠标滚动的动感菜单效果
Sep 21 Javascript
js密码强度实时检测代码
Mar 02 Javascript
基于jQuery代码实现圆形菜单展开收缩效果
Feb 13 Javascript
关于HTML5的data-*自定义属性的总结
May 05 Javascript
vue中Element-ui 输入银行账号每四位加一个空格的实现代码
Sep 14 Javascript
vue路由导航守卫和请求拦截以及基于node的token认证的方法
Apr 07 Javascript
如何在Node和浏览器控制台中打印彩色文字
Jan 09 Javascript
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
May 30 Javascript
React中使用外部样式的3种方式(小结)
May 28 #Javascript
vue实现多条件和模糊搜索功能
May 28 #Javascript
vue实现路由切换改变title功能
May 28 #Javascript
Vue 无限滚动加载指令实现方法
May 28 #Javascript
vue实现搜索过滤效果
May 28 #Javascript
微信小程序 image组件遇到的问题
May 28 #Javascript
vue实现搜索功能
May 28 #Javascript
You might like
php多文件上传下载示例分享
2014/02/20 PHP
页面利用渐进式JPEG来提升用户体验度
2014/12/01 PHP
smarty简单应用实例
2015/11/03 PHP
thinkPHP下ueditor的使用方法详解
2015/12/26 PHP
js电信网通双线自动选择技巧
2008/11/18 Javascript
JavaScript版DateAdd和DateDiff函数代码
2012/03/01 Javascript
Javascript基础教程之数组 array
2015/01/18 Javascript
jquery实现的缩略图预览滑块实例
2015/06/25 Javascript
JQuery日期插件datepicker的使用方法
2016/03/03 Javascript
JavaScript判断页面加载完之后再执行预定函数的技巧
2016/05/17 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
Javascript 事件冒泡机制详细介绍
2016/10/10 Javascript
在JS中a标签加入单击事件屏蔽href跳转页面
2016/12/16 Javascript
35个最好用的Vue开源库(史上最全)
2019/01/03 Javascript
vue悬浮可拖拽悬浮按钮的实例代码
2019/08/20 Javascript
layui自己添加图片按钮并点击跳转页面的例子
2019/09/14 Javascript
JS深入学习之数组对象排序操作示例
2020/05/01 Javascript
微信小程序 scroll-view的使用案例代码详解
2020/06/11 Javascript
python文件和目录操作函数小结
2014/07/11 Python
Python学习教程之常用的内置函数大全
2017/07/14 Python
Python实现Pig Latin小游戏实例代码
2018/02/02 Python
在PyCharm环境中使用Jupyter Notebook的两种方法总结
2018/05/24 Python
python实现Dijkstra算法的最短路径问题
2019/06/21 Python
Python lambda表达式原理及用法解析
2020/08/18 Python
如何以Winsows Service方式运行JupyterLab
2020/08/30 Python
以色列的身体护理及家居香薰品牌:Sabon NYC
2018/02/23 全球购物
植村秀加拿大官网:Shu Uemura加拿大
2019/09/03 全球购物
澳大利亚床上用品、浴巾和家居用品购物网站:Bambury
2020/04/16 全球购物
库存图片、照片、矢量图、视频和音乐:Shutterstock
2021/02/12 全球购物
销售会计岗位职责
2014/03/15 职场文书
2014年班主任自我评价范文
2014/04/23 职场文书
测绘工程专业求职信
2014/07/15 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
新入职员工工作总结
2015/10/15 职场文书
八年级作文之我的母亲
2019/12/10 职场文书
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python