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 相关文章推荐
网上抓的一个特效
May 11 Javascript
Javascript中的this绑定介绍
Sep 22 Javascript
详解JavaScript的变量和数据类型
Nov 27 Javascript
javascript实现根据汉字获取简拼
Sep 25 Javascript
微信小程序 教程之WXML
Oct 18 Javascript
文件上传,iframe跨域数据提交的实现
Nov 18 Javascript
JS中的三个循环小结
Jun 20 Javascript
JavaScript正则表达式校验与递归函数实际应用实例解析
Aug 04 Javascript
详解angular2.x创建项目入门指令
Oct 11 Javascript
解决vue 单文件组件中样式加载问题
Apr 24 Javascript
js 将线性数据转为树形的示例代码
May 28 Javascript
Javascript Symbol原理及使用方法解析
Oct 22 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修改session_id示例代码
2014/01/08 PHP
ThinkPHP实现带验证码的文件上传功能实例
2014/11/01 PHP
smarty模板引擎中自定义函数的方法
2015/01/22 PHP
详解php伪造Referer请求反盗链资源
2019/01/24 PHP
laravel中Redis队列监听中断的分析
2020/09/14 PHP
js中parseFloat(参数1,参数2)定义和用法及注意事项
2013/01/27 Javascript
JavaScript基础语法、dom操作树及document对象
2014/12/02 Javascript
JQuery实现图片轮播效果
2015/09/15 Javascript
jquery及js实现动态加载js文件的方法
2016/01/21 Javascript
基于bootstrap的选择框插件icheck
2016/12/23 Javascript
js制作可以延时消失的菜单
2017/01/13 Javascript
简单实现nodejs上传功能
2017/01/14 NodeJs
捕获未处理的Promise错误方法
2017/10/13 Javascript
详解如何用babel转换es6的class语法
2018/04/03 Javascript
Angularjs之ngModel中的值验证绑定方法
2018/09/13 Javascript
js继承的这6种方式!(上)
2019/04/23 Javascript
vue自动化路由的实现代码
2019/09/30 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
vue路由切换时取消之前的所有请求操作
2020/09/01 Javascript
[02:07]2018DOTA2亚洲邀请赛主赛事第三日五佳镜头 fy极限反杀
2018/04/06 DOTA
python实现忽略大小写对字符串列表排序的方法
2014/09/25 Python
Python编程使用tkinter模块实现计算器软件完整代码示例
2017/11/29 Python
Python安装Flask环境及简单应用示例
2019/05/03 Python
pytorch常见的Tensor类型详解
2020/01/15 Python
对tensorflow中tf.nn.conv1d和layers.conv1d的区别详解
2020/02/11 Python
英国天然保健品网站:Simply Supplements
2017/03/22 全球购物
波兰最大的儿童服装连锁店之一:5.10.15.
2018/02/11 全球购物
大学毕业生简单自荐信
2013/11/05 职场文书
法律系毕业生自荐信范文
2014/03/27 职场文书
家庭教育的心得体会
2014/09/01 职场文书
优秀教师申报材料
2014/12/16 职场文书
2015年音乐教学工作总结
2015/07/22 职场文书
学习新党章心得体会2016
2016/01/15 职场文书
《惊弓之鸟》教学反思
2016/02/20 职场文书
CPU不支持Windows11系统怎么办
2021/11/21 数码科技
基于Python实现将列表数据生成折线图
2022/03/23 Python