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 相关文章推荐
通过JS来判断页面控件是否获取焦点
Jan 03 Javascript
js实现日期级联效果
Jan 23 Javascript
js中this用法实例详解
May 05 Javascript
JS实现的3D拖拽翻页效果代码
Oct 31 Javascript
跟我学习javascript的prototype使用注意事项
Nov 17 Javascript
JavaScript中split与join函数的进阶使用技巧
May 03 Javascript
非常实用的js验证框架实现源码 附原理方法
Jun 08 Javascript
javascript中的后退和刷新实现方法
Nov 10 Javascript
Bootstrap导航简单实现代码
Mar 06 Javascript
Vue.js 2.0学习教程之从基础到组件详解
Apr 24 Javascript
BootStrap 页签切换失效的解决方法
Aug 17 Javascript
微信小程序实现倒计时功能
Nov 19 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自动更新新闻DIY
2006/10/09 PHP
php若干单维数组遍历方法的比较
2011/09/20 PHP
discuz图片顺序混乱解决方案
2015/07/29 PHP
PHP之将POST数据转化为字符串的实现代码
2016/11/03 PHP
php实现文章评论系统
2019/02/18 PHP
深入浅析安装PhpStorm并激活的步骤详解
2020/09/17 PHP
总结AJAX相关JS代码片段和浏览器模型
2007/08/15 Javascript
jQuery DOM操作小结与实例
2010/01/07 Javascript
js限制文本框输入长度两种限制方式(长度、字节数)
2012/12/19 Javascript
formvalidator验证插件中有关ajax验证问题
2013/01/04 Javascript
使用JavaScript动态设置样式实现代码(2)
2013/01/25 Javascript
在firefox和Chrome下关闭浏览器窗口无效的解决方法
2014/01/16 Javascript
ie7+背景透明文字不透明超级简单的实现方法
2014/01/17 Javascript
jQuery时间轴插件使用详解
2015/07/16 Javascript
python使用os模块的os.walk遍历文件夹示例
2014/01/27 Python
PyCharm使用教程之搭建Python开发环境
2016/06/07 Python
python多线程方式执行多个bat代码
2016/06/07 Python
python使用pycharm环境调用opencv库
2018/02/11 Python
Django中针对基于类的视图添加csrf_exempt实例代码
2018/02/11 Python
python自动查询12306余票并发送邮箱提醒脚本
2018/05/21 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
python制作图片缩略图
2019/04/30 Python
python输入错误后删除的方法
2019/10/12 Python
python实现计算器功能
2019/10/31 Python
Python基于network模块制作电影人物关系图
2020/06/19 Python
如何用Python 实现全连接神经网络(Multi-layer Perceptron)
2020/10/15 Python
CSS实现半透明边框与多重边框的场景分析
2019/11/13 HTML / CSS
VC++笔试题
2014/10/13 面试题
函授毕业生自我鉴定范文
2014/03/25 职场文书
协议书怎么写
2014/04/21 职场文书
餐饮投资计划书
2014/04/25 职场文书
慈善晚会策划方案
2014/05/14 职场文书
横店影视城导游词
2015/02/06 职场文书
作弊检讨书范文
2015/05/06 职场文书
2016年学校爱国卫生月活动总结
2016/04/06 职场文书
golang 生成对应的数据表struct定义操作
2021/04/28 Golang