树结构列表结构相互转换 js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>js树结构列表转化</title> </head> <body> <script> let tree = [ { id: '1', title: '节点1', children: [ { id: '1-1', title: '节点1-1' }, { id: '1-2', title: '节点1-2' } ] }, { id: '2', title: '节点2', children: [ { id: '2-1', title: '节点2-1' } ] } ] // 广度优先 function treeForeach1(tree, func) { let node, list = [...tree] while (node = list.shift()) { // node = undefined node = list.shift() 刪除第一個 node赋值成功 func(node) node.children && list.push(...node.children) // 在最後追加数组 } } treeForeach1(tree, node => { console.log(node.title) }) /** * 节点1 * 节点2 * 节点1-1 * 节点1-2 * 节点2-1 */ // 先序遍历 递归 function treeForeach2(tree, func) { tree.forEach(data => { func(data) data.children && treeForeach2(data.children, func) // 遍历子树 递归的条件 data.children存在 }) } treeForeach2(tree, node => { console.log(node.title) }) /** * 节点1 * 节点1-1 * 节点1-2 * 节点2 * 节点2-1 */ // 后序遍历 递归 function treeForeach3(tree, func) { tree.forEach(data => { data.children && treeForeach3(data.children, func) // 遍历子树 递归的条件 data.children存在 func(data) }) } treeForeach3(tree, node => { console.log(node.title) }) /** * 节点1-1 * 节点1-2 * 节点1 * 节点2-1 * 节点2 */ // 深度优先遍历 循环 function treeForeach4(tree, func) { let node, list = [...tree] while (node = list.shift()) { func(node) node.children && list.unshift(...node.children) } } treeForeach4(tree, node => { console.log(node.title) }) /** * 节点1 * 节点1-1 * 节点1-2 * 节点2 * 节点2-1 */ // 深度后序遍历 循环 function treeForeach4(tree, func) { let node, list = [...tree], i = 0 while (node = list[i]) { let childCount = node.children ? node.children.length : 0 if (!childCount || node.children[childCount - 1] === list[i - 1]) { func(node) i++ } else { list.splice(i, 0, ...node.children) } } } treeForeach4(tree, node => { console.log(node.title) }) /** * 节点1-1 * 节点1-2 * 节点1 * 节点2-1 * 节点2 */ // <--------------------------------===========================-----------------------------> let list = [ { id: '1', title: '节点1', parentId: '', }, { id: '1-1', title: '节点1-1', parentId: '1' }, { id: '1-2', title: '节点1-2', parentId: '1' }, { id: '2', title: '节点2', parentId: '' }, { id: '2-1', title: '节点2-1', parentId: '2' } ] function listToTree1(list) { let funb = (map, node) => (map[node.id] = node, node.children = [], map) let info = list.reduce(funb, {}) return list.filter(node => { info[node.parentId] && info[node.parentId].children.push(node) return !node.parentId }) } let list2 = listToTree1(list); console.log(list2); /** * (2) [{…}, {…}] */ // 树结构==》列表结构 // 递归实现 function treeToList1(tree, result = [], level = 0) { tree.forEach(node => { result.push(node) node.level = level + 1 node.children && treeToList1(node.children, result, level + 1) }) return result } let list3 = treeToList1(list2); console.log(list3) /** * [{…}, {…}, {…}, {…}, {…}] */ // 循环实现 function treeToList2(tree) { let node, result = tree.map(node => (node.level = 1, node)) for (let i = 0; i < result.length; i++) { if (!result[i].children) continue let list = result[i].children.map(node => (node.level = result[i].level + 1, node)) result.splice(i + 1, 0, ...list) } return result } let list4 = treeToList2(list2); console.log(list4); /** * [{…}, {…}, {…}, {…}, {…}] */ </script> </body> </html>
参考链接:https://mp.weixin.qq.com/s/2fYDzu1Qz6CPBBUOQlTX6A
To b or not To b
is Not a Q