扁平数据和树形数据的处理

142 阅读1分钟

前言

关于数据处理相信大家在工作中经常会遇到扁平数据转树形结构的数据,树形结构的数据转为扁平化的数据,来回转换,今天我也遇到啦,条条大道通罗马,如果有更好的办法还请赐教!

//扁平数据
    source = [{
            id: 1,
            pid: 0,
            name: 'body'
        }, {
            id: 2,
            pid: 1,
            name: 'title'
        }, {
            id: 3,
            pid: 2,
            name: 'div'
    }]
//tree数据
  tree = [{
        id: 1,
        pid: 0,
        name: 'body',
        children: [{
            id: 2,
            pid: 1,
            name: 'title',
            children: [{
                id: 3,
                pid: 1,
                name: 'div'
            }]
        }
    }]

首先我的思路是这样的

  1. 先筛选出扁平数据中的父级节点
  2. 遍历父级节点查找子节点
  3. 如果父节点children属性已创建就可以递归查找

function toTree(arr){
    let parents=arr.filter(item=>!item.pid)//筛选父级元素
    return arr.reduce((prev,next)=>{
        return arrFind(prev,next)//循环调用
    },parents)
    function arrFind(arr,target){
        return arr.map(item=>{//遍历查找
            if(item.id===target.pid){
                item.children=item.children?item.children.push(target):[target]
            }else if(item.children){
                arrFind(item.children,target) //递归遍历
            }
            return item
        })
    }
}

反之

  1. 给每个节点添加id并且都是唯一的
  2. 如果节点有children属性,递归遍历并且传入父节点id
  3. 删除children属性,添加到数组中
function toFlatArr(arr,targetarr=[]){
     let initId=0;//id初始值
     flat(arr)
     function flat(arr,pid=0){
        arr.map(item=>{
            item.id=++initId
            item.pid=pid
            if(Array.isArray(item.children)){
                flat(item.children,item.id)//深度遍历,并且传入父级节点id
            }
            delete item.children//遍历完成之后删除children属性
            targetarr.push(item)
        })
     }
     return targetarr
 }

如果有写的不对的地方还望大家及时指正!