const treeData=[
{id:1,
name:'中國',
children:[
{id:11,name:'河南省',children:[{id:111,name:'南陽市',children:[{id:1111,name:'淅川縣',children:null}]},{id:112,name:'鄭州市',children:[{id:1121,name:'中牟縣',children:null}]}]
},
{id:22,name:'廣東省',children:[{id:221,name:'深圳市',children:[{id:2211,name:'寶安區',children:null},{id:2212,name:'福田區',children:null}]},{id:222,name:'廣州市',children:[{id:2221,name:'天河區',children:null},{id:2222,name:'南沙區',children:null}]}]
}]}
]
const listData1=[
{id:1,name:'中國'},
{id:11,name:'河南省',pid:1},
{id:111,name:'南陽市',pid:11},
{id:1111,name:'淅川縣',pid:111},
{id:112,name:'鄭州市',pid:11},
{id:1121,name:'中牟縣',pid:112},
{id:12,name:'廣東省',pid:1},
{id:121,name:'深圳市',pid:12},
{id:1211,name:'寶安區',pid:121},
{id:1212,name:'福田區',pid:121},
{id:122,name:'廣州市',pid:12},
{id:1221,name:'天河區',pid:122},
{id:1222,name:'南沙區',pid:122},
]
1、一維數組轉樹形結構
1.1、遞歸
//一維數組轉樹形結構
function listToTree(list){const tree=[]for(const node of list){//如果是父節點if(!node.pid){let p={...node}p.children=getChildren(p.id,list)tree.push(p)}}return tree
}
function getChildren(id,list){const children=[]//遍歷數組的每一個元素,如果找到元素的父元素節點等于當前節點,則向children中添加該元素for(const node of list){if(node.pid===id){children.push(node)}}//遍歷每一個孩子節點,遞歸尋找孩子的孩子節點,如果存在children,則向node的children中添加for(const node of children){const children=getChildren(node.id,list)if(children.length){node.children=children}}return children
}
demo:
console.log(listToTree(listData))
打印后的結果和treeData一致。
1.2、雙層循環
// 雙層循環:找出每一個元素的父節點,向每一個父節點增加children屬性
function listToTree2(list){list.forEach(child=>{const pid=child.pid//遍歷子節點,然后遍歷每一個list節點,從中找出父節點,向父節點增加孩子元素if(pid){list.forEach(parent=>{if(parent.id===pid){//如果找到的父節點還沒有孩子,會默認為空數組,否則為原來的子節點數組 parent.children=parent.children||[]parent.children.push(child)}})}})
}
結果同1.1
1.3、使用map
//Map
function listToListMap(list){const [map,treeData]=[{},[]]//將map轉為以id為key,索引為value的對象//將數組中每個元素的children初始化為空數組for(let i=0;i<list.length;i++){map[list[i].id]=i;list[i].children=[]}console.log(map)for(let i=0;i<list.length;i++){const node=list[i]//如果是子元素并且子元素的父節點存在在list中,則找到父元素并向父元素的children中加入子元素if(node.pid&&list[map[node.pid]]){list[map[node.pid]].children.push(node)}else{//說明不是子元素,是父元素直接放入treeData中treeData.push(node)}}return treeData
}
2、tree轉list
樹形結構轉數組涉及到樹的遍歷,樹的遍歷分為深度遍歷(前中后序)和廣度遍歷。
2.1、廣度遍歷
const treeData3=[
{id:1,
name:'中國',
children:[
{id:11,name:'河南省',children:[{id:111,name:'南陽市',pid:11,children:[{id:1111,name:'淅川縣',children:null,pid:111,}]},{id:112,name:'鄭州市',pid:11,children:[{id:1121,pid:112,name:'中牟縣',children:null}]}]
},
{id:22,name:'廣東省',children:[{id:221,pid:22,name:'深圳市',children:[{id:2211,pid:221,name:'寶安區',children:null},{id:2212,pid:221,name:'福田區',children:null}]},{id:222,pid:22,name:'廣州市',children:[{id:2221,pid:222,name:'天河區',children:null},{id:2222,pid:222,name:'南沙區',children:null}]}]
}]}
]
//廣度遍歷(一層一層遍歷)
function treeToList(treeData){const list=[]const queue=[...treeData]while(queue.length){//取隊頭元素 const node=queue.shift()const children=node.children//將隊頭元素的孩子依次放入隊列中便于后序遍歷if(children){queue.push(...children)}//放入元素節點list.push(node)}return list
}
console.log(treeToList(treeData3))
打印結果同1中的listData
2.2、深度遍歷
//深度遍歷(采用棧)
function treeToList2(tree){const list=[]const stack=[...tree]while(stack.length){const node=stack.pop()//如果出棧的節點有孩子元素,那么將出棧元素的所有孩子元素都放入棧中,便于后續遍歷.const children=node.childrenif(children){stack.push(...children)}list.push(node)}return list
}
3、list轉Map(map是以父節點id為key,所有子節點作為數組為value的數據結構)
const listData4=[
{id:1,name:'中國'},//0
{id:11,name:'河南省',pid:1},//1
{id:111,name:'南陽市',pid:11},//2
{id:1111,name:'淅川縣',pid:111},//3
{id:112,name:'鄭州市',pid:11},//4
{id:1121,name:'中牟縣',pid:112},//5
{id:12,name:'廣東省',pid:1},//6
{id:121,name:'深圳市',pid:12},//7
{id:1211,name:'寶安區',pid:121},//8
{id:1212,name:'福田區',pid:121},//9
{id:122,name:'廣州市',pid:12},//10
{id:1221,name:'天河區',pid:122},//11
{id:1222,name:'南沙區',pid:122},//12
]
// 將列表數據轉為以父節點id為key,子節點為value的map
function listToMap(list){const map={}list.forEach(item=>{for(let i=0;i<list.length;i++){//如果外層循環元素的id等于內層循環元素的pid,說明內層元素是外層元素的子元素,則向map的value中添加該內層元素.if(list[i].pid===item.id){map[item.id]=map[item.id]||[]map[item.id].push(list[i])}}})return map
}
console.log(listToMap(listData4))
?