JS實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)與數(shù)組結(jié)構(gòu)相互轉(zhuǎn)換并在樹(shù)形結(jié)構(gòu)中查找對(duì)象
總是有很多需求是關(guān)于處理樹(shù)形結(jié)構(gòu)的,所以不得不總結(jié)幾個(gè)常見(jiàn)操作的寫(xiě)法。
首先假設(shè)有一個(gè)樹(shù)形結(jié)構(gòu)數(shù)據(jù)如下
var tree=[
{
'id': '1',
'name': '教學(xué)素材管理',
'children':[
{
'id': '101',
'name': '教學(xué)素材',
'children':[
{
'id': '10101',
'name': '修改',
},
{
'id': '10102',
'name': '添加',
}
]
}, {
'id': '102',
'name': '測(cè)試試題',
},
{
'id': '103',
'name': '問(wèn)題任務(wù)',
}
]
}, {
'id': '2',
'name': '基礎(chǔ)數(shù)據(jù)管理',
'children':[
{
'id': '201',
'name': '專(zhuān)業(yè)設(shè)置',
},
{
'id': '202',
'name': '專(zhuān)業(yè)管理',
}
]
}
]1、如何在tree中找到id=10102的對(duì)象?
思路一:深度遍歷,從頂點(diǎn)開(kāi)始,當(dāng)前節(jié)點(diǎn)有子節(jié)點(diǎn)則遍歷當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)(遞歸)。
function deepQuery(tree,id) {
var isGet = false;
var retNode = null;
function deepSearch(tree,id){
for(var i = 0; i<tree.length; i++) {
if(tree[i].children && tree[i].children.length>0) {
deepSearch(tree[i].children,id);
}
if(id === tree[i].id || isGet) {
isGet||(retNode = tree[i]);
isGet = true;
break;
}
}
}
deepSearch(tree,id);
return retNode;
}調(diào)用:
var getNode = deepQuery(tree,10102); console.log(getNode)
思路二:廣度遍歷,遍歷根節(jié)點(diǎn)的所有子節(jié)點(diǎn),再?gòu)牡谝粋€(gè)子節(jié)點(diǎn)開(kāi)始依次遍歷。
function breadthQuery(tree, id) {
var stark = [];
stark = stark.concat(tree);
while(stark.length) {
var temp = stark.shift();
if(temp.children) {
stark = stark.concat(temp.children);
}
if(temp.id === id) {
return temp;
}
}
}調(diào)用:
var getNode=breadthQuery(tree,10102); console.log(getNode);
2、如何將樹(shù)形結(jié)構(gòu)轉(zhuǎn)換為有父子關(guān)系屬性的數(shù)組結(jié)構(gòu)?
思路一:初始化一個(gè)空數(shù)組,從tree的頂端開(kāi)始遍歷,當(dāng)前節(jié)點(diǎn)有子節(jié)點(diǎn)時(shí),一邊繼續(xù)遍歷子節(jié)點(diǎn),一邊在當(dāng)前節(jié)點(diǎn)上刪除子節(jié)點(diǎn),將當(dāng)前節(jié)點(diǎn)push到空數(shù)組。
function flatten1(tree) {
var arr = [];
function spread(tree,pid) {
for (var i=0; i < tree.length; i++ ) {
item = tree[i]
let {id,name}=item;
arr.push({id,name,pid})
if (item.children) {
spread(item.children,item.id)
delete item.children
}
}
}
spread(tree,0)
return arr;
}
var newArr = flatten1(tree);思路二:
function flatten2 (data,pid) {
return data.reduce((arr, {id, name, children = []}) =>
arr.concat([{id, name,pid}], flatten2(children,id)), [])
}
var newArr = flatten2(tree,0);結(jié)果:

3、如何將數(shù)組結(jié)構(gòu)轉(zhuǎn)換為樹(shù)形結(jié)構(gòu)?
下面是偶然看到一位大佬很秀的寫(xiě)法(原文鏈接)
function treeData(data){
let cloneData = JSON.parse(JSON.stringify(data))
return cloneData.filter(parent=>{
let branchArr = cloneData.filter(child => parent['id'] == child['pid']);
branchArr.length>0 ? parent['children'] = branchArr : '';
return parent['pid'] == 0 ;
})
}調(diào)用:
var newTree = treeData(newArr)
用之前測(cè)試生成的數(shù)組試一下

結(jié)果如上,完美的生成了最初的樹(shù)形結(jié)構(gòu)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript設(shè)計(jì)模式之Adapter模式【適配器模式】實(shí)現(xiàn)方法示例
這篇文章主要介紹了javascript設(shè)計(jì)模式之Adapter模式,結(jié)合實(shí)例形式分析了JS適配器模式的原理與具體實(shí)現(xiàn)方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01
在b/s開(kāi)發(fā)中經(jīng)常用到的javaScript技術(shù)
在b/s開(kāi)發(fā)中經(jīng)常用到的javaScript技術(shù)...2006-08-08
JavaScript創(chuàng)建對(duì)象的七種方式(推薦)
JavaScript創(chuàng)建對(duì)象的方式有很多,通過(guò)Object構(gòu)造函數(shù)或?qū)ο笞置媪康姆绞揭部梢詣?chuàng)建單個(gè)對(duì)象,顯然這兩種方式會(huì)產(chǎn)生大量的重復(fù)代碼,并不適合量產(chǎn)。接下來(lái)介紹七種非常經(jīng)典的創(chuàng)建對(duì)象的方式,他們也各有優(yōu)缺點(diǎn)2017-06-06
js+HTML5 canvas 實(shí)現(xiàn)簡(jiǎn)單的加載條(進(jìn)度條)功能示例
這篇文章主要介紹了js+HTML5 canvas 實(shí)現(xiàn)簡(jiǎn)單的加載條(進(jìn)度條)功能,涉及javascript使用時(shí)間函數(shù)與canvas繪圖結(jié)合實(shí)現(xiàn)進(jìn)度條的相關(guān)操作技巧,需要的朋友可以參考下2019-07-07
JavaScript的concat方法實(shí)例代碼(數(shù)組連接)
這篇文章主要介紹了JavaScript的concat方法實(shí)例代碼,包括數(shù)組連與字符連接,需要的朋友可以參考下2023-03-03
JS實(shí)現(xiàn)圖片點(diǎn)擊后出現(xiàn)模態(tài)框效果
這篇文章主要介紹了JS實(shí)現(xiàn)圖片點(diǎn)擊后出現(xiàn)模態(tài)框效果,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05
postMessage消息通信Promise化的方法實(shí)現(xiàn)
postMessage Api 想必大家都不陌生,WebWorker 通信會(huì)用到,iframe 窗口之間通信也會(huì)用到,那么我們能不能將 postMessage 進(jìn)行一次轉(zhuǎn)化,把他變成類(lèi)似 Promise 的使用方式,所以本文給大家介紹了postMessage消息通信Promise化的方法實(shí)現(xiàn),需要的朋友可以參考下2024-03-03
js實(shí)現(xiàn)京東秒殺倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)京東秒殺倒計(jì)時(shí)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01

