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 相关文章推荐
json 实例详细说明教程
Oct 31 Javascript
今天是星期几的4种JS代码写法
Sep 17 Javascript
IE下window.onresize 多次调用与死循环bug处理方法介绍
Nov 12 Javascript
js实现用户注册协议倒计时的方法
Jan 21 Javascript
jquery实现用户信息修改验证输入方法汇总
Jul 18 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
Aug 11 Javascript
Javascript 使用ajax与C#获取文件大小实例详解
Jan 13 Javascript
javascript事件的绑定基础实例讲解(34)
Feb 14 Javascript
jquery实现左右轮播切换效果
Jan 01 jQuery
Node.js系列之连接DB的方法(3)
Aug 30 Javascript
vue动态禁用控件绑定disable的例子
Oct 28 Javascript
Vue根据条件添加click事件的方式
Nov 09 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使用cookie保存登录用户名的方法
2015/01/26 PHP
Yii输入正确验证码却验证失败的解决方法
2017/06/06 PHP
PhpStorm2020.1 安装 debug - Postman 调用的详细教程
2020/08/17 PHP
JavaScript 继承机制的实现(待续)
2010/05/18 Javascript
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
2012/10/11 Javascript
js实现杯子倒水问题自动求解程序
2013/03/25 Javascript
js禁止页面刷新禁止用F5键刷新禁止右键的示例代码
2013/09/23 Javascript
Js实现双击鼠标自动滚动屏幕的示例代码
2013/12/14 Javascript
JS去除字符串两端空格的简单实例
2013/12/27 Javascript
jQuery选择器简明总结(含用法实例,一目了然)
2014/04/25 Javascript
jquery实现键盘左右翻页特效
2015/04/30 Javascript
JavaScript Promise 用法
2016/06/14 Javascript
JS使用JSON作为参数实例分析
2016/06/23 Javascript
简单实现js浮动框
2016/12/13 Javascript
javascript中apply/call和bind的使用
2017/02/15 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
2017/08/20 Javascript
微信小程序 scroll-view 水平滚动实现过程解析
2019/10/12 Javascript
vue Treeselect 树形下拉框:获取选中节点的ids和lables操作
2020/08/15 Javascript
python list使用示例 list中找连续的数字
2014/01/27 Python
Python中列表元素转为数字的方法分析
2016/06/14 Python
Python使用pymysql小技巧
2017/06/04 Python
Python随机生成手机号、数字的方法详解
2017/07/21 Python
python使用Tesseract库识别验证
2018/03/21 Python
一篇文章弄懂Python中所有数组数据类型
2019/06/23 Python
关于jupyter打开之后不能直接跳转到浏览器的解决方式
2020/04/13 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
2020/09/21 Python
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
2012/06/04 HTML / CSS
HTML5拖拽API经典实例详解
2018/04/20 HTML / CSS
Kneipp克奈圃美国官网:德国百年精油配方的传承
2018/02/07 全球购物
Hotels.com加拿大:领先的在线住宿网站
2018/10/05 全球购物
Ibatis如何使用动态表名
2015/07/12 面试题
中式餐厅创业计划书范文
2014/01/23 职场文书
先进班集体事迹材料
2014/12/25 职场文书
2015年万圣节活动总结
2015/03/24 职场文书
搞笑结婚保证书
2015/05/08 职场文书
SpringBoot2 参数管理实践之入参出参与校验的方式
2021/06/16 Java/Android