昨天遇到一道面试题,手写js将json数组转成tree对象,昨天写错了,今天特意想了下,思路其实挺简单,循环+递归,获取子节点对象。

1 let data = [
2     {'parent_id': 0, 'id': 1, 'value': 'XXX'},
3     {'parent_id': 1, 'id': 3, 'value': 'XXX'},
4     {'parent_id': 4, 'id': 6, 'value': 'XXX'},
5     {'parent_id': 3, 'id': 5, 'value': 'XXX'},
6     {'parent_id': 2, 'id': 4, 'value': 'XXX'},
7     {'parent_id': 1, 'id': 2, 'value': 'XXX'},
8 ]

 

主要方法如下,使用的是es6语法

 1 let toTree = (arr, key = 'id', pkey = 'pid', children='children') => {
 2      if(arr.length === 0){
 3          return {}
 4      }
 5      return getChildren(arr, 0) // 此处的0代表根节点,如有的根节点标识符为'#',那么此处则为'#'
 6       
 7    // 主要原理是通过查找父节点parent_id为pid的对象,再一层一层往下查找子节点id,看是否存在parent_id等于id的对象
 8      function getChildren(arr, pid) {
 9          let temp = {}
10         arr.forEach(v => {
11             if(v[pkey] === pid){
12                 temp[v[key]] = {} // 此处可根据相应需求作调整
13                 if(Object.keys(getChildren(arr, v[key])).length !== 0){ // 如果存在子节点,此处也可将递归方法抽离出来,以减少代码量和操作
14                     temp[v[key]][children] = getChildren(arr, v[key]) // 此处可根据相应需求作调整
15                 }
16             }
17         })
18         return temp
19     }
20 }

 

测试数据

 1 let tree = toTree(data)
 2 console.log(JSON.stringify(tree))
 3 
 4 // 结果为:
 5 {
 6     "1": {
 7         "children": {
 8             "2": {
 9                 "children": {
10                     "4": {
11                         "children": {
12                             "6": {}
13                         }
14                     }
15                 }
16             },
17             "3": {
18                 "children": {
19                     "5": {}
20                 }
21             }
22         }
23     }
24 }

 

posted on 2018-06-28 21:13  _linka  阅读(963)  评论(0编辑  收藏  举报