跳至主要內容

树结构转换

wzCoding大约 3 分钟综合知识树结构转换

树结构转换

在开发当中,我们经常会遇到树形结构的数据,有时我们需要将数据转换为树结构渲染展示,有时有需要将树结构数据展开铺平从而方便我们进行数据处理。

数据

有如下符合树结构的数据:

const list = [
   { name:'1'},
   { name:'1-1', parent:'1'},
   { name:'1-1-1', parent:'1-1'},
   { name:'1-2', parent:'1'},
   { name:'1-2-1', parent:'1-2'},
   { name:'1-3', parent:'1'},
   { name:'2', parent:null},
   { name:'2-1', parent:'2'},
   { name:'2-1-1', parent:'2-1'},
   { name:'2-2', parent:'2'},
   { name:'2-2-1', parent:'2-2'},
   { name:'2-1-1-1', parent:'2-1-1'},
]

转换为树结构

将如上的数据转换为树结构,具体代码如下:

function getTree(list){
   if (!list || !list.length) {
      return
   }

   const tree = []   // 存放结果
   const map = {}  // 存放对象映射关系

   for (let item of list) {
      //假设每个节点都有子节点,为每个节点添加 children 属性
      item.children = []

      // 使用对象的 name 属性作为 map 的 key 值,对应的对象为 value,建立对象映射关系
      map[item.name] = { ...item }

      if (item.parent) {
            // 如果存在 parent 属性,说明它是某个节点的子节点
            map[item.parent].children.push(map[item.name])
      } else {
            // 如果没有 parent 属性,说明它是根节点
            tree.push(map[item.name])
      }
   }

   return tree
}
// 使用
// 这里使用上面的 list 数据
const listToTree = getTree(list)
console.log(listToTree)
// 输出:
// [
//     {
//         "name": "1",
//         "children": [
//             {
//                 "name": "1-1",
//                 "parent": "1",
//                 "children": [
//                     {
//                         "name": "1-1-1",
//                         "parent": "1-1",
//                         "children": []
//                     }
//                 ]
//             },
//             {
//                 "name": "1-2",
//                 "parent": "1",
//                 "children": [
//                     {
//                         "name": "1-2-1",
//                         "parent": "1-2",
//                         "children": []
//                     }
//                 ]
//             },
//             {
//                 "name": "1-3",
//                 "parent": "1",
//                 "children": []
//             }
//         ]
//     },
//     {
//         "name": "2",
//         "parent": null,
//         "children": [
//             {
//                 "name": "2-1",
//                 "parent": "2",
//                 "children": [
//                     {
//                         "name": "2-1-1",
//                         "parent": "2-1",
//                         "children": [
//                             {
//                                 "name": "2-1-1-1",
//                                 "parent": "2-1-1",
//                                 "children": []
//                             }
//                         ]
//                     }
//                 ]
//             },
//             {
//                 "name": "2-2",
//                 "parent": "2",
//                 "children": [
//                     {
//                         "name": "2-2-1",
//                         "parent": "2-2",
//                         "children": []
//                     }
//                 ]
//             }
//         ]
//     }
// ]

树结构展开

将树结构的数据展开,具体代码如下:

//接收一个树结构的数据、子节点的key的名称、一个存放结果的数组作为参数
function expandTree(tree, childKey = 'children', list = []) {
   if (!tree || !tree.length) {
      return
   }
   
   //遍历树结构
   for (let item of tree) {
      list.push(item)
      //如果子节点存在并且子节点包含其他节点
      if (item[childKey] && item[childKey].length) {
            //递归调用此方法
            expandTree(item[childKey], childKey, list)
      }
   }

   return list
}

// 使用
// 这里使用已经转换为树结构的数据 listToTree
const treeToList = expandTree(listToTree,'children')
console.log(treeToList)
//输出:
// [
//     {name: '1', children: Array(3)},
//     {name: '1-1', parent: '1', children: Array(1)},
//     {name: '1-1-1', parent: '1-1', children: Array(0)},
//     {name: '1-2', parent: '1', children: Array(1)},
//     {name: '1-2-1', parent: '1-2', children: Array(0)}
//     {name: '1-3', parent: '1', children: Array(0)},
//     {name: '2', parent: null, children: Array(2)},
//     {name: '2-1', parent: '2', children: Array(1)},
//     {name: '2-1-1', parent: '2-1', children: Array(1)},
//     {name: '2-1-1-1', parent: '2-1-1', children: Array(0)},
//     {name: '2-2', parent: '2', children: Array(1)},
//     {name: '2-2-1', parent: '2-2', children: Array(0)}
// ]