本文实例讲述了js 递归json树实现根据子id查父id的方法。分享给大家供大家参考,具体如下:
最近做了一个类似用js实现思维导图的功能,作为思维导图,一定会有树状结构的数据产生,在操作里面的节点时会经常需要查找节点 的父节点及父节点。
对于未知层级的树状数据,用for循环是无法实现的,因为不知道要循环几层,那么最合适的方法就是用js递归
界面结构:
json数据:
"orgTreeData":{ "nodeId":"19A5B", "nodeName":"预分析用户:1313.85万人", "nodeType":"root", "expand":true, "dataCnt":13138494, "children":[ { "nodeId":"19A5B_19A5C", "nodeName":"客户状态", "nodeType":"tag", "children":[ { "nodeId":"19A5B_19A5C_19A5E", "nodeName":"包含(实名制停机,IPBUS帐户封锁停机)", "dataCnt":"0人", "nodeType":"domain", "counted":2, "children":[ { "nodeId":"19A5B_19A5C_19A5E_19A67", "nodeName":"积分", "nodeType":"tag", "children":[ ], "expand":true, "counted":0, "condType":"1", "dataType":1, "propType":"1", "propSql":"", "labelId":"BLD00013", "linked":false, "linkedId":"" }, { "nodeId":"19A5B_19A5C_19A5E_19A68", "nodeName":"是否通信客户", "nodeType":"tag", "children":[ ], "expand":true, "counted":0, "condType":"3", "dataType":1, "propType":"4", "propSql":"", "labelId":"BLD00010", "linked":false, "linkedId":"" } ], "expand":true, "expressType":"7", "expressValue1":[ "17", "14" ], "expressValue2":"", "expressValue3":"17##14", "expressValue4":"实名制停机##IPBUS帐户封锁停机", "expressValue5":"实名制停机,IPBUS帐户封锁停机", "linked":false, "linkedId":"" }, { "nodeId":"19A5B_19A5C_19A60", "nodeName":"包含(营业销户)", "dataCnt":"0人", "nodeType":"domain", "counted":2, "children":[ { "nodeId":"19A5B_19A5C_19A60_19A69", "nodeName":"入网归属地域", "nodeType":"tag", "children":[ { "nodeId":"19A5B_19A5C_19A60_19A69_19A6A", "nodeName":"包含(鄂尔多斯,阿盟)", "dataCnt":"", "nodeType":"domain", "counted":0, "children":[ ], "expand":true, "expressType":"7", "expressValue1":[ "477", "482" ], "expressValue2":"", "expressValue3":"477##482", "expressValue4":"鄂尔多斯##阿盟", "expressValue5":"鄂尔多斯,阿盟", "linked":false, "linkedId":"" } ], "expand":true, "counted":0, "condType":"2", "dataType":1, "propType":"3", "propSql":"1005", "labelId":"BLD00017", "linked":false, "linkedId":"" } ], "expand":true, "expressType":"7", "expressValue1":[ "40" ], "expressValue2":"", "expressValue3":"40", "expressValue4":"营业销户", "expressValue5":"营业销户", "linked":false, "linkedId":"" } ], "expand":true, "counted":0, "condType":"2", "dataType":1, "propType":"3", "propSql":"1002", "labelId":"BLD00004", "linked":false, "linkedId":"" }, { "nodeId":"19A5B_19A61", "nodeName":"全球通级别 && 全球通级别", "nodeType":"tag", "children":[ ], "expand":true, "counted":0, "condType":"2", "dataType":1, "propType":"3", "propSql":"1004", "labelId":"BLD00008", "linked":true, "linkedId":"19A5B_19A64" }, { "nodeId":"19A5B_19A62", "nodeName":"同证件号码数量", "nodeType":"tag", "children":[ ], "expand":true, "counted":0, "condType":"1", "dataType":1, "propType":"1", "propSql":"", "labelId":"BLD00009", "linked":false, "linkedId":"" } ] }
我这个对象结构是按nodeId匹配的,每个下级为children数组。
如果我想点击任何一个节点根据节点nodeId得到它的父节点nodeId,就得把整个json树递归遍历一遍,知道找到这个节点,从而得到它的父节点
关于递归,一定要掌握好结束条件,懂得何时return,不然会出现返回不出值或者循环提前结束的情况。
js代码:
//传入参数:需要遍历的json,需要匹配的id findPnodeId(data,nodeId){ //设置结果 let result; if (!data) { return;//如果data传空,直接返回 } for (var i = 0; i < data.children.length; i++) { let item = data.children[i]; if (item.nodeId == nodeId) { result=data.nodeId; //找到id相等的则返回父id return result; } else if (item.children && item.children.length > 0) { //如果有子集,则把子集作为参数重新执行本方法 result= findPnodeId(item, nodeId); //关键,千万不要直接return本方法,不然即使没有返回值也会将返回return,导致最外层循环中断,直接返回undefined,要有返回值才return才对 if(result){ return result; } } } //如果执行循环中都没有return,则在此return return result; }
总之,递归相当于上图中的轨迹查找。
条件执行到 需要 重新执行 findPnodeId 方法的地方开始一头扎进去,如果第下一次执行找到了符合条件的值,则return出来,返回上一层,下一层的 findPnodeId 方法结束,返回值,上一层的findPnodeId方法也就直接return结束了。
如果下一层方法 进入循环第一次依然没有找到 符合的值 ,如果还有子集,则会继续向更下一层进发;就像上图中的红线,直到没有子集才结束,所以千万不让直接 在递归 findPnodeId 方法前直接return,也就是这样:
else if (item.children && item.children.length > 0) { return findPnodeId(item, nodeId); }
这样会使 json在第一条树轨迹结束时(上图中的红色轨迹)如果找不到值 强制 retrun undefined,因为没一个方法都向上return,for循环中,一旦return,会直接打断循环,使方法结束,结果是最底层 的undefined 直接return到顶层,顶层直接将undefined return出来,根本没有走第234条线,所以一定要先判断一下是否返回值再return,像这样:
} else if (item.children && item.children.length > 0) { result= this.findPnodeId(item, nodeId); if(result){ return result; } }
那么如果方法前不写return会怎样?
是方法无法return,依然无法递归
PS:关于json操作,这里再为大家推荐几款比较实用的json在线工具供大家参考使用:
在线JSON代码检验、检验、美化、格式化工具:
http://tools.jb51.net/code/json
JSON在线格式化工具:
http://tools.jb51.net/code/jsonformat
在线XML/JSON互相转换工具:
http://tools.jb51.net/code/xmljson
json代码在线格式化/美化/压缩/编辑/转换工具:
http://tools.jb51.net/code/jsoncodeformat
在线json压缩/转义工具:
http://tools.jb51.net/code/json_yasuo_trans
更多关于JavaScript相关内容可查看本站专题:《JavaScript中json操作技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 群星《2024好听新歌36》AI调整音效【WAV分轨】
- 梁朝伟.1986-朦胧夜雨裡(华星40经典)【华星】【WAV+CUE】
- 方芳.1996-得意洋洋【中唱】【WAV+CUE】
- 辛欣.2001-放120个心【上海音像】【WAV+CUE】
- 柏菲·万山红《花开原野1》限量开盘母带ORMCD[低速原抓WAV+CUE]
- 柏菲·万山红《花开原野2》限量开盘母带ORMCD[低速原抓WAV+CUE]
- 潘安邦《思念精选集全纪录》5CD[WAV+CUE]
- 杨千嬅《千嬅新唱金牌金曲》金牌娱乐 [WAV+CUE][985M]
- 杨钰莹《依然情深》首版[WAV+CUE][1G]
- 第五街的士高《印度激情版》3CD [WAV+CUE][2.4G]
- 三国志8重制版哪个武将智力高 三国志8重制版智力武将排行一览
- 三国志8重制版哪个武将好 三国志8重制版武将排行一览
- 三国志8重制版武将图像怎么保存 三国志8重制版武将图像设置方法
- 何方.1990-我不是那种人【林杰唱片】【WAV+CUE】
- 张惠妹.1999-妹力新世纪2CD【丰华】【WAV+CUE】