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 相关文章推荐
用JQuery实现表格隔行变色和突出显示当前行的代码
Feb 10 Javascript
为JS扩展Array.prototype.indexOf引发的问题探讨及解决
Apr 24 Javascript
JSON格式化输出
Nov 10 Javascript
jQuery中extend函数详解
Feb 13 Javascript
jQuery 监控键盘一段时间没输入
Apr 22 Javascript
有趣的bootstrap走动进度条
Dec 01 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
May 22 Javascript
AngularJS中controller控制器继承的使用方法
Nov 03 Javascript
JS中用EL表达式获取上下文参数值的方法
Mar 28 Javascript
详解vue 2.6 中 slot 的新用法
Jul 09 Javascript
微信小程序实现树莓派(raspberry pi)小车控制
Feb 12 Javascript
javascript中闭包closure的深入讲解
Mar 03 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 开发环境配置(Zend Server安装)
2010/04/28 PHP
php simplexmlElement操作xml的命名空间实现代码
2011/01/04 PHP
smarty简单分页的实现方法
2014/10/27 PHP
PHP通过串口实现发送短信
2015/07/08 PHP
关于php几种字符串连接的效率比较(详解)
2017/02/22 PHP
document.getElementById为空或不是对象的解决方法
2010/01/24 Javascript
javascript 子窗体父窗体相互传值方法
2010/05/31 Javascript
javascript对select标签的控制(option选项/select)
2013/01/31 Javascript
jquery中加载图片自适应大小主要实现代码
2013/08/23 Javascript
实例分析js和C#中使用正则表达式匹配a标签
2014/11/26 Javascript
Bootstrap模态框使用详解
2017/02/15 Javascript
jQuery插件FusionCharts绘制2D双折线图效果示例【附demo源码】
2017/04/14 jQuery
webpack+vue.js构建前端工程化的详细教程
2020/05/10 Javascript
JavaScript实现世界各地时间显示
2020/09/07 Javascript
Python 变量类型及命名规则介绍
2013/06/08 Python
python3 面向对象__类的内置属性与方法的实例代码
2018/11/09 Python
python卸载后再次安装遇到的问题解决
2019/07/10 Python
简单了解python反射机制的一些知识
2019/07/13 Python
python正则爬取某段子网站前20页段子(request库)过程解析
2019/08/10 Python
Python利用for循环打印星号三角形的案例
2020/04/12 Python
python代码中怎么换行
2020/06/17 Python
一款纯css3实现的漂亮的404页面的实例教程
2014/11/27 HTML / CSS
详解Html5 Canvas画线有毛边解决方法
2018/03/01 HTML / CSS
东方电视购物:东方CJ
2016/10/12 全球购物
斯德哥尔摩通票:Stockholm Pass
2018/01/09 全球购物
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
DJI大疆德国官方商城:大疆无人机
2018/09/01 全球购物
如何在Oracle中查看各个表、表空间占用空间的大小
2015/10/31 面试题
公司经理任命书
2014/06/05 职场文书
总经理助理岗位职责范本
2014/07/20 职场文书
计划生育汇报材料
2014/12/26 职场文书
2015政治思想表现评语
2015/03/25 职场文书
理想国读书笔记
2015/06/25 职场文书
Python中文纠错的简单实现
2021/07/07 Python
Python进行区间取值案例讲解
2021/08/02 Python
JavaScript中时间格式化新思路toLocaleString()
2021/11/07 Javascript