線性結構與樹形結構相互轉換(ES6實現)
阿新 • • 發佈:2018-04-22
tlist 結構 fin 更多 color {} 完整 pre ID
前言
當樹形結構的層級越來越深時,操作某一節點會變得越來越費勁,維護成本不斷增加。所以線性結構與樹形的相互轉換變得異常重要!
首先,我們約定樹形結構如下:
node = { id: number, // 數值
parentId: number, // 數值 name: string,
children: [] || null, // 用數組的方式保存子節點,適合更多業務場景 }
線性結構:
list = [ { id: number, parentId: number, name: string }, { id: number, parentId: number, name: string }, ];
特殊情況
上面的樹形結構並不是很完美,當遇到菜單或者分類等業務場景時,每個頂級節點的parentId約定為0,當存在多個頂級節點,顯得不是一個完整的樹。所以在這類特殊情況下,我們需要構造一個頂級節點。將菜單或者分類的原有頂級節點存儲至該節點的children中。 所以最後約定頂級節點如下。
root = null || { id: 0, parentId: null, children: [node1, node2, ...], }
線性結構與樹形結構相互轉換
線性轉樹形:
function listConvertTree(list) { let root= null; if (list && list.length) { root = { id: 0, parentId: null, children: [] }; const group = {}; for (let index = 0; index < list.length; index += 1) { if (list[index].parentId !== null && list[index].parentId !== undefined) { if (!group[list[index].parentId]) { group[list[index].parentId]= []; } group[list[index].parentId].push(list[index]); } } const queue = []; queue.push(root); while (queue.length) { const node = queue.shift(); node.children = group[node.id] && group[node.id].length ? group[node.id] : null; if (node.children) { queue.push(...node.children); } } } return root; }
樹形轉線性:
function treeConvertList(root) { const list = []; if (root) { const Root = JSON.parse(JSON.stringify(root)); const queue = []; queue.push(Root); while (queue.length) { const node = queue.shift(); if (node.children && node.children.length) { queue.push(...node.children); } delete node.children; if (node.parentId !== null && node.parentId !== undefined) { list.push(node); } } } return list; }
線性結構與樹形結構相互轉換(ES6實現)