博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript将具有父子关系的原始数据格式化成树形结构数据(id,pid)
阅读量:4606 次
发布时间:2019-06-09

本文共 2753 字,大约阅读时间需要 9 分钟。

前几天遇到一个树型组件(类似树形菜单)数据格式化的问题,由于后台把原始查询的数据直接返回给前端,父子关系并未构建,因此需要前端JS来完成,后台返回的数据和下面的测试数据相似。

1 var data=[2 {id:1,pid:0,text:'A'},3 {id:2,pid:4,text:"E[父C]"},4 {id:3,pid:7,text:"G[父F]"},5 {id:4,pid:1,text:"C[父A]"},6 {id:5,pid:6,text:"D[父B]"},7 {id:6,pid:0,text:'B'},8 {id:7,pid:4,text:"F[父C]"}9 ];

我们可以发现上面的测试数据有几个特点,父节点与子节点不是顺序排列的,也就是说按照id的顺序,并不是先有父节点,然后有下面的子节点,顺序是混乱的,再就是父子层级有很多,这里是3层。总结为:顺序混乱,层级未知。

如果是顺序排列,层级固定,可以投机取巧,写法相对简单,但是这里恰恰相反。因此给格式化造成了一定的困难,当遇到层级未知的时候,一般都会想到递归的写法,这里我感觉用递归也不好做,因此我也就没有向这方面去深入思考,这里就也不做多的说明。

那么我的做法比起递归来讲更容易理解,先看下代码。

1 function toTreeData(data){ 2     var pos={}; 3     var tree=[]; 4     var i=0; 5     while(data.length!=0){ 6         if(data[i].pid==0){ 7             tree.push({ 8                 id:data[i].id, 9                 text:data[i].text,10                 children:[]11             });12             pos[data[i].id]=[tree.length-1];    13             data.splice(i,1);14             i--;15         }else{16             var posArr=pos[data[i].pid];17             if(posArr!=undefined){18                 19                 var obj=tree[posArr[0]];20                 for(var j=1;j
data.length-1){36 i=0;37 }38 }39 return tree;40 }

前面的测试数据经过上面代码中的方法格式化后如下:

[    {        "id": 1,        "text": "A",        "children": [            {                "id": 4,                "text": "C[父A]",                "children": [                    {                        "id": 7,                        "text": "F[父C]",                        "children": [                            {                                "id": 3,                                "text": "G[父F]",                                "children": []                            }                        ]                    },                    {                        "id": 2,                        "text": "E[父C]",                        "children": []                    }                ]            }        ]    },    {        "id": 6,        "text": "B",        "children": [            {                "id": 5,                "text": "D[父B]",                "children": []            }        ]    }]

原理很简单,使用一个死循环来遍历数组,循环跳出的条件是数组的长度为0,也就是说,循环内部会引起数组长度的改变。这里就几个关键点做一下说明。

  1. 为什么要用死循环?顺序混乱,如果单次循环,子节点出现在父节点之前,子节点不好处理,这里做一个死循环相当于先把父节点全部找出,但是这里又不是简单的先把所有的父节点找出,找的同时,如果这个节点父节点已经找到,那么可以继续做后续操作;
  2. 如何建立层级关系?代码中有一个变量pos,这个用于保存每个已添加到tree中的节点在tree中位置信息,比如上面测试数据父节点A添加到tree后,那么pos中增加一条数据,pos={”1“:[0]},1就是父节点A的id,这样写便于查找,[0]表示父节点A在tree的第一个元素,即tree[0],如果某个位置信息为[1,2,3],那么表示这个节点在tree[1].children[2].children[3],这里的位置关系其实就是父子的层级关系。

上面的测试数据的pos信息如下:

1 {2     "1":[0],3     "2":[0,0,1],4     "3":[0,0,0,0],5     "4":[0,0],6     "5":[1,0],7     "6":[1],8     "7":[0,0,0]9 }

 

转载于:https://www.cnblogs.com/exhuasted/p/7416543.html

你可能感兴趣的文章
忘记管理员密码的补救办法
查看>>
PHP - 如何实现跨域
查看>>
PowerShell 多线程测试IP端口
查看>>
mysql表修复脚本
查看>>
实战mongodb3.06 Relica Sets+sharding集群
查看>>
关于自动化测试的思考
查看>>
Android Studio第三十六期 - 模块化Activity管理Fragment
查看>>
SaltStack安装配置与远程执行测试
查看>>
Android Studio第十五期 - 友盟统计集成
查看>>
Android内核开发:序
查看>>
部署tomcat负载均衡集群,实现节点之间内存中的Session共享。
查看>>
如何测试WEB应用程序防止SQL注入***
查看>>
TFS版本管理(八)
查看>>
【VMCloud云平台】SCO(五)制作流程(一)
查看>>
从NDK在非Root手机上的调试原理探讨Android的安全机制
查看>>
八大深层志趣——问问你自己到底喜欢做什么工作
查看>>
通过刷bios的方式在win8.1平板上启动windows phone模拟器
查看>>
一道企业shell编程实战题-看看谁能快速搞定
查看>>
Windows Server8下补丁分发配置与iSCSI配置
查看>>
Ubuntu系统(十)-Web服务配置
查看>>