我们在实际的工作业务场景中经常遇到这样的场景,求取树数据中某个节点的父亲节点以及所有的父亲节点,这样的场景下不建议使用深度遍历,使用广度遍历可以更快找到。

1、案例解说

比如树的长相是这样的:

树的数据是这样的:

是我们常用的树的数据及长相。

2、业务要求

在【测试抽取5】后面新增一个节点,要求

1)接口要求传入当前节点的父节点;

2)新增后重新获取树数据,默认展开所有的父级

3、代码实现及说明

思路:

1)设定一个排队数组parentIdsQueue 将树数据开始排队;

2)如果当前数据有孩子节点,将孩子节点倒序加入队列中,因为遍历的时候是从第一个数据开始的;

3)如果当前数据有孩子节点,在孩子加入队列前,把父亲节点的数据放到parentArr中;

4)如果找到了节点,如果是第一层的节点,直接获取即可;如果包括parentArr,则parentArr中的全是它的父级节点

多说无益,先上实现代码

// id 指的是当前点击的节点id;
findParentNode (id) {
// 初始化所需数据
this.firstParentObj = {}; // 记录直系父级的名称和id即接口要传的数据
this.parentIds = []; // 记录所有的父级ids
this.parentIdsQueue = []; // 记录排队的 // 将树放到排队系列
this.parentIdsQueue = this.treeData; // 开始遍历排队的树
while (this.parentIdsQueue.length) {
//抽取第一个排队的数据
let item = this.parentIdsQueue.shift(); let { children } = item;
if (item.id === id) {
// 第一层就找到了
if (!item.parentArr) {
this.firstParentObj = {
id: item.id,
name: item.title
};
this.parentIds = [item.id];
} else {
// 获取当前节点的parentArr
let len = item.parentArr.length;
this.firstParentObj = item.parentArr[len - 1];
item.parentArr.forEach(a => {
this.parentIds.push(a.id);
}); this.parentIds.push(item.id);
} // 结束遍历
this.parentIdsQueue = [];
break;
} else if (children && children.length) {
let len = children.length;
for (let i = len - 1; i >= 0; i--) {
// 新建一个数组用于记录它的父亲节点
children[i].parentArr = []; // 把它的历史父亲节点们先放入
if (item.parentArr) {
children[i].parentArr = children[i].parentArr.concat(
item.parentArr
);
} // 再放入当前的父亲节点
children[i].parentArr.push({
id: item.id,
name: item.title
}); // 加入到排队序列中
this.parentIdsQueue.unshift(children[i]);
}
}
}
}

5、结果演示

我们在文前举的例子中添加个节点,现在来打印出所需的数据

     console.log("测试抽取5的所有父亲",item.parentArr);
console.log("接口所需的父亲节点数据",this.firstParentObj);
console.log("设置树展开所需的所有父亲节点数据节点id", this.parentIds);

如图所示,我们已经实现了相关的功能。至于树的展开,获取的所有的父亲节点,遍历树id在parentIds中的设置其expand为true即可。

记录JS如何使用广度遍历找到节点的所有父节点的更多相关文章

  1. Element ui tree树形控件获取当前节点id和父节点id

    低版本Element ui tree树形控件获取当前节点id和父节点id的方法:点击查看 最新版本Element ui tree树形控件获取当前节点id和父节点id教程: 1.找到node_modul ...

  2. T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

    -- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316-- ...

  3. [SQL]T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)

    T-Sql 递归查询(给定节点查所有父节点.所有子节点的方法)   -- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ ...

  4. Treeview控件如何获得子节点的所有父节点的名称

    Delphi或c++ 的treeview控件,比如一个节点上面有个父节点,这个父节点上面还有一个父节点,如何获得这两个父节点的名字呢?请给出实现代码 先定义一个nodevarnode:TTreeNod ...

  5. 遍历DOM树,获取父节点

    通过获取父节点,还可以获取父节点的父节点. 有3个常用方法: 方法  说明  parent()  选取父节点  parents()  选取所有父节点  parentsUntil("div&q ...

  6. easyui Tree模拟级联勾选cascadeCheck,节点选择,父节点自动选中,节点取消,父节点自动取消选择,节点选择,所有子节点全部选择,节点取消,所有子节点全部取消勾选

    最近项目中用到easyui tree,发现tree控件的cascadeCheck有些坑,不像miniui 的tree控件,级联勾选符合业务需求,所以就自己重新改写了onCheck事件,符合业务需求.网 ...

  7. 你真的会玩SQL吗?查询指定节点及其所有父节点的方法

    --查询ID = '009'的所有父节点 ' ;WITH T AS ( SELECT ID , PID , NAME FROM TB WHERE ID = @ID UNION ALL SELECT A ...

  8. javascript : 找到一个树型数据的一个节点及其所有父节点

    如题. (function () { let tree = { "id": 0, "label": "all", "childre ...

  9. extjs4 树列表 添加子节点 刷新所有父节点数据

    itemclick:function(view, record, item,index){console.log(record.parentNode) for(pNode = record.paren ...

随机推荐

  1. 获取mysql自主生成的主键

    一.sql语句 CREATE TABLE `testgeneratedkeys` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) ...

  2. Python(Head First)学习笔记:三

    3 文件与异常:调试.处理错误.迭代.改进.完善  处理错误:利用Python的异常处理机制来处理异常情况.  程序外部的数据:大多程序基本模型:首先输入数据,进行处理,然后存储.显示.打印或传输. ...

  3. FreeSql (二)自动迁移实体

    FreeSql 支持 CodeFirst 迁移结构至数据库,这应该是(O/RM)必须标配的一个功能. 与其他(O/RM)不同FreeSql支持更多的数据库特性,而不只是支持基础的数据类型,这既是优点也 ...

  4. android 定时提醒 - Notification

    定时弹出 demo ,代码如下: 1.MainActivity.java public class MainActivity extends Activity implements OnClickLi ...

  5. 正则表达式(RegExp)

    前言:先来了解一下基础知识.再细说正则表达式~ 转义字符  ----   \ 转义字符会将与之相邻的字符转换含义. 例如说,希望在一个字符串中输出 “ 号,那么就可以使用在双引号前加入 \ ,这样就能 ...

  6. Elastic Stack 笔记(二)Elasticsearch5.6 安装 IK 分词器和 Head 插件

    博客地址:http://www.moonxy.com 一.前言 Elasticsearch 作为开源搜索引擎服务器,其核心功能在于索引和搜索数据.索引是把文档写入 Elasticsearch 的过程, ...

  7. caffe学习一:ubuntu16.04下跑Faster R-CNN demo (基于caffe). (亲测有效,记录经历两天的吐血经历)

    兜兜转转,兜兜转转; 一次有一次,这次终于把Faster R-CNN 跑通了. 重要提示1:在开始跑Faster R-CNN之前一定要搞清楚用的是Python2 还是Python3. 不然你会无限次陷 ...

  8. 在.NET Core中使用DispatchProxy“实现”非公开的接口

    原文地址:"Implementing" a non-public interface in .NET Core with DispatchProxy 原文作者:Filip W. 译 ...

  9. java教程系列二:Java JDK,JRE和JVM分别是什么?

    多情只有春庭月,犹为离人照落花. 概述 本章主要了解JDK,JRE和JVM之间的区别.JVM是如何工作的?什么是类加载器,解释器和JIT编译器.还有一些面试问题. Java程序执行过程 在深入了解Ja ...

  10. SpringMVC 图片上传虚拟目录

    可以直接在tomcat的server.xml文件中进行设置,位置在Host中 添加内容为:<Context docBase="G:\JAVAtest\temp" path=& ...