樹結構你們應該都比較熟悉,這裏我主要說兩種:一個根節點和多個根節點。
一個根節點,就像咱們的html節點,不可能有和它同級的;多個根節點,好比咱們的一二級導航欄。
下面一個個分析:html
let arr = [ { menuId: 1, name: '系統1', parentMenu: null }, { menuId: 2, name: '系統1_0', parentMenu: 1 }, { menuId: 3, name: '系統1_1', parentMenu: 1 } ] function turnToTreeOfOneRoot(arr) { if (!Array.isArray(arr)) { throw new Error('is not array') } else { return arr.reduce((cur, item) => { if (item.parentMenu == null) { cur = { children: [], ...item } } else if (item.parentMenu == cur.menuId) { cur.children.push(item) } return cur }, {}) } } turnToTreeOfOneRoot(arr)
var arr1 = [ { menuId: 1, name: '系統管理1', parentMenu: null }, { menuId: 2, name: '系統管理1_0', parentMenu: 1 }, { menuId: 3, name: '系統管理1_1', parentMenu: 1 }, { menuId: 4, name: '系統管理2_0', parentMenu: 2 } ] function turnToTreeOfOneRootPlus(arr) { var obj = {} arr.forEach(item => { if (item.parentMenu == null) { obj = item } }) return arr.reduce((h, m) => { // 若是不是根節點 if (m.parentMenu) { foo(h, m) } // 在obj裏面爲cur找到歸宿 function foo(obj, cur) { if (obj.menuId === cur.parentMenu) { if (!obj.children) { obj.children = [] } obj.children.push(cur) } else if (obj.children) { obj.children.forEach(item => { foo(item, cur) }) } } return h }, obj) } turnToTreeOfOneRootPlus(arr1)
let arr2 = [ { menuId: 1, name: '系統1', parentMenu: null }, { menuId: 2, name: '系統1_0', parentMenu: 1 }, { menuId: 3, name: '系統1_1', parentMenu: 1 }, { menuId: 4, name: '系統2', parentMenu: null }, { menuId: 5, name: '系統4_0', parentMenu: 4 } ] function turnToTreeOfManyRoot(arr) { if (!Array.isArray(arr)) { throw new Error('is not array') } else { var roots = [] arr.forEach(item => { if (item.parentMenu == null) { item.children = [] roots.push(item) } }) return arr.reduce((roots, cur) => { roots.forEach(item => { // 若是是根節點 if (item.menuId == cur.parentMenu) { item.children.push(cur) } }) return roots }, roots) } } turnToTreeOfManyRoot(arr2)
var arr3 = [ { menuId: 1, name: '系統管理1', parentMenu: null }, { menuId: 2, name: '系統管理2', parentMenu: null }, { menuId: 3, name: '系統管理1_0', parentMenu: 1 }, { menuId: 4, name: '系統管理1_1', parentMenu: 1 }, { menuId: 5, name: '系統管理2_0', parentMenu: 2 }, { menuId: 6, name: '系統管理5_0', parentMenu: 5 }, { menuId: 7, name: '系統管理3', parentMenu: null } ] function turnToTreeOfManyRootPlus(arr) { var arrs = [] arr.forEach(item => { if (!item.parentMenu) { arrs.push(item) } }) return arr.reduce((h, m) => { if (m.parentMenu) { foo(h, m) } function foo(arr, cur) { arr.forEach(item => { if (item.menuId === cur.parentMenu) { if (!item.children) { item.children = [] } item.children.push(cur) } else if (item.children) { foo(item.children, cur) } }) } return h }, arrs) } turnToTreeOfManyRootPlus(arr3)
ps:最後提醒一下,數組裏面的對象必定是排序過的,也就是說父級必定在前面,它的子級必定在後面。好比:json
let arr = [ { menuId: 1, name: '系統1', parentMenu: null }, { menuId: 4, name: '系統2_0', parentMenu: 2 }, { menuId: 2, name: '系統1_0', parentMenu: 1 }, { menuId: 3, name: '系統1_1', parentMenu: 1 } ]
這樣的數組,會致使menuId: 4
丟失。由於它的父級在後面,因此遍歷到它時沒辦法塞給它的父級。謹記:必定要排好序,而後進行數組遍歷數組