私たちは、多くの場合、ノードにデータツリーのノードを取得し、そのような場面では、実際のビジネスシナリオの仕事で遭遇し、すべての父ノードの父は、このようなシナリオは、より迅速に見つけることができる幅トラバーサルを使用して、深さトラバーサルをお勧めしません。
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
することができそうです。