js 递归json树实现根据子id查父id的方法分析


Posted in Javascript onNovember 08, 2019

本文实例讲述了js 递归json树实现根据子id查父id的方法。分享给大家供大家参考,具体如下:

最近做了一个类似用js实现思维导图的功能,作为思维导图,一定会有树状结构的数据产生,在操作里面的节点时会经常需要查找节点 的父节点及父节点。

对于未知层级的树状数据,用for循环是无法实现的,因为不知道要循环几层,那么最合适的方法就是用js递归

界面结构:

js 递归json树实现根据子id查父id的方法分析

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;
}

js 递归json树实现根据子id查父id的方法分析

总之,递归相当于上图中的轨迹查找。

条件执行到 需要 重新执行 findPnodeId 方法的地方开始一头扎进去,如果第下一次执行找到了符合条件的值,则return出来,返回上一层,下一层的 findPnodeId 方法结束,返回值,上一层的findPnodeId方法也就直接return结束了。

js 递归json树实现根据子id查父id的方法分析

如果下一层方法 进入循环第一次依然没有找到 符合的值 ,如果还有子集,则会继续向更下一层进发;就像上图中的红线,直到没有子集才结束,所以千万不让直接 在递归 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,依然无法递归

Javascript 相关文章推荐
扩展jQuery 键盘事件的几个基本方法
Oct 30 Javascript
关于Aptana Studio生成自动备份文件的解决办法
Dec 23 Javascript
再谈javascript 动态添加样式规则 W3C校检
Dec 25 Javascript
jQuery EasyUI API 中文文档 - Spinner微调器使用
Oct 21 Javascript
让jQuery与其他JavaScript库并存避免冲突的方法
Dec 23 Javascript
jquery ajax应用中iframe自适应高度问题解决方法
Apr 12 Javascript
Javascript动态创建div的方法
Feb 09 Javascript
理解javascript异步编程
Jan 27 Javascript
jQuery autoComplete插件两种使用方式及动态改变参数值的方法详解
Oct 24 Javascript
如何快速上手Vuex
Feb 14 Javascript
JS实现页面打印功能
Mar 16 Javascript
vue中如何实现后台管理系统的权限控制的方法步骤
Sep 05 Javascript
BootstrapValidator验证用户名已存在(ajax)
Nov 08 #Javascript
微信小程序在text文本实现多种字体样式
Nov 08 #Javascript
浅谈vuex的基本用法和mapaction传值问题
Nov 08 #Javascript
微信小程序select下拉框实现源码
Nov 08 #Javascript
使用kbone解决Vue项目同时支持小程序问题
Nov 08 #Javascript
在VUE中实现文件下载并判断状态的方法
Nov 08 #Javascript
vue中在vuex的actions中请求数据实例
Nov 08 #Javascript
You might like
浅析php中jsonp的跨域实例
2013/06/21 PHP
js 日期转换成中文格式的函数
2009/07/07 Javascript
子窗口、父窗口和Silverlight之间的相互调用
2010/08/16 Javascript
JS关闭窗口与JS关闭页面的几种方法小结
2013/12/17 Javascript
详解angularjs中的隔离作用域理解以及绑定策略
2017/05/31 Javascript
VUE元素的隐藏和显示(v-show指令)
2017/06/23 Javascript
详解EasyUi控件中的Datagrid
2017/08/23 Javascript
基于iScroll实现内容滚动效果
2018/03/21 Javascript
详解javascript 正则表达式之分组与前瞻匹配
2018/05/30 Javascript
深入理解vue-class-component源码阅读
2019/02/18 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
谈谈IntersectionObserver懒加载的具体使用
2019/10/15 Javascript
element中el-container容器与div布局区分详解
2020/05/13 Javascript
vue过滤器实现日期格式化的案例分析
2020/07/02 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
[01:58]DOTA2上海特级锦标赛现场采访:RTZ这个ID到底好不好
2016/03/25 DOTA
一篇文章快速了解Python的GIL
2018/01/12 Python
Python脚本完成post接口测试的实例
2018/12/17 Python
解决python文件双击运行秒退的问题
2019/06/24 Python
python @classmethod 的使用场合详解
2019/08/23 Python
TFRecord格式存储数据与队列读取实例
2020/01/21 Python
Python利用matplotlib绘制折线图的新手教程
2020/11/05 Python
美国家居装饰网上商店:Lulu & Georgia
2019/09/14 全球购物
车间操作工岗位职责
2013/12/19 职场文书
趣味活动策划方案
2014/02/08 职场文书
运动会宣传口号
2014/06/09 职场文书
大学生就业自荐书
2014/06/16 职场文书
新手上路标语
2014/06/20 职场文书
会计试用期自我评价
2014/09/19 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书
ktv服务员岗位职责
2015/02/09 职场文书
内勤岗位职责范本
2015/04/13 职场文书
企业财务管理制度范本
2015/08/04 职场文书
生产车间管理制度
2015/08/04 职场文书
Nginx 安装SSL证书完成HTTPS部署
2022/04/28 Servers
springcloud整合seata
2022/05/20 Java/Android