扁平数组转tree与 tree数据扁平化代码

542 阅读2分钟

image.png

前言

在工作时候,提供数据的接口给到的数据可能不是理想的,那么此时就要求前端程序员,具有改造数据的能力。

类型

下面是将举两个数据改造的例子:

  1. 反扁平化,扁平结构的 flat 数据,转换为具有层级递进关系的 tree 数据

  2. 扁平化,具有层级递进关系的 tree 数据,转换为扁平结构的的 flat 数据

一、扁平数据转为tree数据

代码

function flatToTree(data) {               
  let result = []  
  //如果值是 Array,则为true; 否则为false。           
  if(!Array.isArray(data)) {                  
      return result       
  }                
  //把每一项的引用放入map对象里             
  let map = {}          
  data.forEach(item => {          
    map[item.id] = item;   
  });   
   
  //再次遍历数组 决定item的去向             
  for(let item of data){
    //父节点,直接放入到result数组中
    if(item.pid === 0){
      result.push(item);
      continue;
    }
    if(item.pid in map){ //in 判断某属性是否在指定对象中
      let parent = map[item.pid];
      parent.children = parent.children || []
      parent.children.push(item)
    }
  }
    return result;          
}            

原始数据

var list = [
  {id: 1, title: '解忧杂货铺1', pid: 0},
  {id: 2, title: '解忧杂货铺2', pid: 0},
  {id: 6, title: '解忧杂货铺4-2', pid: 2},
  {id: 3, title: '解忧杂货铺2-1', pid: 2},
  {id: 4, title: '解忧杂货铺3-1', pid: 3},
  {id: 5, title: '解忧杂货铺4-1', pid: 4}
]

运行结果

image.png

二、tree数据转为扁平数据

代码

function treeToFlat(data) {
  return data.reduce(function(arr, {id, title, pid, children = []}){  //解构赋值+默认值
    return arr.concat([{id, title, pid}], treeToFlat(children)) //children部分进行递归
  },[]);
}

原始数据

let JsonTree = [
  {id: 1, title: '解忧杂货铺1', pid: 0},
  {
    id: 2, title: '解忧杂货铺2', pid: 0, children: 
    [
      {id: 6, title: '解忧杂货铺4-2', pid: 2},
      {
        id: 3, title: '解忧杂货铺2-1', pid: 2, children: 
        [
          {
            id: 4, title: '解忧杂货铺3-1', pid: 3, children: 
            [
              {id: 5, title: '解忧杂货铺4-1', pid: 4},
            ]
          },
        ]
      },
    ]
  }
  ];

运行结果

image.png

总结

这两个扁平化与反扁平化写法,感觉还有值得优化的方法,但暂时想不到。