在一些前端開發過程中,我們通常需要將後臺查詢出來的集合數據進行相應的轉換,轉成樹形結構對象,比如常用的評論區數據就是一種典型的樹形結構數據,如下圖所示。
而後臺服務端傳來的數據通常是一種普通的集合(元素中有 id 和 pid ,以此構成 父子節點關係)它們是一種數組集合對象(服務端可能是List集合 ,前端爲json對象或json串),如下圖所示
[{
"CODE": "6",
"PID": "0",
"ID": "6",
"NAME": "天安門金領總校"
}, {
"CODE": "101",
"PID": "6",
"ID": "101",
"NAME": "校辦"
}, {
"CODE": "102",
"PID": "6",
"ID": "102",
"NAME": "市場部"
}, {
"CODE": "103",
"PID": "6",
"ID": "103",
"NAME": "學術部"
}, {
"CODE": "104",
"PID": "6",
"ID": "104",
"NAME": "教質就業部"
}, {
"CODE": "102101",
"PID": "102",
"ID": "102101",
"NAME": "網諮部"
}, {
"CODE": "102102",
"PID": "102",
"ID": "102102",
"NAME": "媒體部"
}, {
"CODE": "102103",
"PID": "102",
"ID": "102103",
"NAME": "諮詢部"
}, {
"CODE": "103101",
"PID": "103",
"ID": "103101",
"NAME": "教員組"
}, {
"CODE": "104101",
"PID": "104",
"ID": "104101",
"NAME": "班主任組"
}, {
"CODE": "104102",
"PID": "104",
"ID": "104102",
"NAME": "就業專員組"
}, {
"CODE": "104103",
"PID": "104",
"ID": "104103",
"NAME": "學員組"
}]
上面的json數據是平行結構(列表)最終在前端構成的展示數據是一棵樹,如下圖所示
那麼,我們如何將平行結構的數據轉化成樹型對象數據(平行二維列表數據轉成有 N層次深度樹形對象) 如下圖所示
節點中如果有subnode屬性,則表明該節點非葉子節點(擁有子節點),圖中顯示了樹形對象的根節點,子節點,孫節點的關係
這裏涉及到常用算法參考如下
遞歸算法反覆構建葉子節點,至到將數組內的所有節點加載到相匹配的父級節點下,具體js代碼參數如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script lang="javascript">
var treelist = [{
"CODE": "6",
"PID": "0",
"ID": "6",
"NAME": "天安門金領總校"
}, {
"CODE": "101",
"PID": "6",
"ID": "101",
"NAME": "校辦"
}, {
"CODE": "102",
"PID": "6",
"ID": "102",
"NAME": "市場部"
}, {
"CODE": "103",
"PID": "6",
"ID": "103",
"NAME": "學術部"
}, {
"CODE": "104",
"PID": "6",
"ID": "104",
"NAME": "教質就業部"
}, {
"CODE": "102101",
"PID": "102",
"ID": "102101",
"NAME": "網諮部"
}, {
"CODE": "102102",
"PID": "102",
"ID": "102102",
"NAME": "媒體部"
}, {
"CODE": "102103",
"PID": "102",
"ID": "102103",
"NAME": "諮詢部"
}, {
"CODE": "103101",
"PID": "103",
"ID": "103101",
"NAME": "教員組"
}, {
"CODE": "104101",
"PID": "104",
"ID": "104101",
"NAME": "班主任組"
}, {
"CODE": "104102",
"PID": "104",
"ID": "104102",
"NAME": "就業專員組"
}, {
"CODE": "104103",
"PID": "104",
"ID": "104103",
"NAME": "學員組"
}];
function initTree(){
createTree(treelist);
}
//將傳入的數據構建成樹型對象
function createTree(treelist){
// alert(treelist.length);
// debugger;
var treeData = new Array();
for(var i = 0 ; i< treelist.length;i++){
//構建一級節點(根節點)
if(treelist[i].PID == '0'){
treeData.push(treelist[i]);
console.log('構建一級節點:'+treelist[i].NAME);
continue; //進入下一個元素處理
}else{ //該元素非一級節點,將其掛在相應的節點下
addNodeToTree(treelist[i],treeData);
}
}
console.log('tree對象構建完成');
debugger;
}
//將node掛在treeData相應的節點下
function addNodeToTree(node ,treeData){
for(var i = 0 ; i< treeData.length;i++){
if(node.PID == treeData[i].ID){//說明是子節點
if(typeof(treeData[i]["subnode"]) == "undefined"){
var subnode = [];
subnode.push(node);
treeData[i]["subnode"] = subnode;
console.log('給父節點:'+treeData[i].NAME+' 添加子節點:'+node.NAME+' 並集合化');
return true;
}else{//該父節點已經存在子節點集合
treeData[i]["subnode"].push(node);
console.log('給父節點:'+treeData[i].NAME+' 添加子節點到集合:'+node.NAME);
return true;
}
}
//說明node節點不是該一級節點的子節點,如果該一級節點有子集合,則有可能是孫,重孫節點
if(typeof(treeData[i]["subnode"]) != "undefined"){
// console.log('需要檢查該節點下的子集合 ID:'+treeData[i].ID+' name:'+treeData[i].NAME);
// debugger;
//開始遞歸
if(addNodeToTree(node,treeData[i]["subnode"])){
return true;
}else{
continue;
}
}
}
console.log('該集合下未匹配到合適的節點:'+node.NAME);
// debugger;
return false;
}
//將樹型數據重新構造
</script>
</head>
<body onload="initTree()">
</body>
</html>