美文网首页
基于js的数组转换为二叉树object

基于js的数组转换为二叉树object

作者: 林玲玲的笔记 | 来源:发表于2021-06-27 12:50 被阅读0次

1.第一种格式转换

转换后的数据格式:

image.png

数据转换的方法:

//递归整理成树形数据
            convert:function(data,parentId){
                let convertData =[];
                data.forEach((item,index)=>{
                    if(item.parent_id===parentId){
                        convertData.push(item);
                        this.convertChild(data,item,item.id);
                    }
                });
                return convertData;
            },
            convertChild:function(arr,parentItem,parentId){
                parentItem.children = parentItem.children?parentItem.children:[];
                arr.forEach(item=>{
                    if(item.parent_id===parentId){
                        parentItem.children.push(item);
                        this.convertChild(arr,item,item.id);
                    }
                });
                return parentItem.children;
            },


//原数据格式
var data =  [
                {id:1,label:"中国",parent_id:0},
                {id:2,label:"北京",parent_id:1},
                {id:3,label:"上海",parent_id:1},
                {id:4,label:"广东",parent_id:1},
                {id:5,label:"广东",parent_id:4},
                {id:6,label:"深圳",parent_id:4},
            ];
//使用
let a=this.convert(data,0);
console.log(a);

2.第二种格式转换

let row = {
    "总经办": {
        "财务部" : {
            "财务总监": "张三"
        },
        "人事部": {
            "人事总监": "李四",
            "人事专员": "小明"
        }
    }
}

let resultList = {};
function dataTotree(data) {
  const result = [];
  Object.keys(data).forEach(key => {
    const item = {
      label: key,
      children: data[key]
    }
    if(item.children instanceof Object) {
      item.children = dataTotree(data[key])
    } else {
      item.children = [{label: data[key]}];
    }
   result.push(item)
  })
  return result;
}
let result = dataTotree(row);
console.log(result[0])

转换后的数据格式如下:


image.png

3.第三种格式转换

①原始数据格式:

var arr = [
        {id: 1, name: '部门1', pid: 0},
        {id: 2, name: '部门2', pid: 1},
        {id: 3, name: '部门3', pid: 1},
        {id: 4, name: '部门4', pid: 3},
        {id: 5, name: '部门5', pid: 4},
    ];

②转换后数据格式:

 //目标:转换后的数据格式示例
    var resultList=[
        {
            "id": 1,
            "name": "部门1",
            "pid": 0,
            "children": [
                {
                    "id": 2,
                    "name": "部门2",
                    "pid": 1,
                    "children": []
                },
                {
                    "id": 3,
                    "name": "部门3",
                    "pid": 1,
                    "children": [
                         {
                            "id": 4,
                            "name": "部门4",
                            "pid": 3,
                            "children": [
                                {
                                    "id": 5,
                                    "name": "部门5",
                                    "pid": 4,
                                    "children": []
                                },
                            ]
                        },
                    ]
                }
            ]
        }
    ]

③方法:
【第一种:递归】

/**
     *递归查询,获取children
     * @param data
     * @param result
     * @param pid
     */
    const  getChildren = (data,result,pid) =>{
        for (const item of data){
            if(item.pid === pid) {
                const newItem = {...item, children: []};
                result.push(newItem);
                getChildren(data, newItem.children, item.id);
            }
        }
    }
    /**
     * 转换方法
     */
    const arrayToTree = (data,pid) =>{
        const result = [];
        getChildren(data,result,pid);
        return result;
    }
    console.log('第一种方式:',arrayToTree(arr,0));

【第二种:Map+对象引用,两次for】

 /**第二种办法(不用递归)
     * 思路:先把数据转成Map存储,之后遍历的同时借助对象的引用,直接从Map找到对应的数据做存储
     * */
    function arrayToTree2(items) {
        const result = [];  //存放结果集合
        const itemMap = {};

        //先转为map存储
        for(const item of items){
            itemMap[item.id] = {...item,children:[]}
        }

        for (const item of items){
            const id = item.id;
            const pid = item.pid;
            const treeItem = itemMap[id];
            if(pid === 0){
                // console.log(treeItem);
                result.push(treeItem);
            }else{
                if(!itemMap[pid]){
                    console.log("itemMap[pid]",itemMap[pid]);
                    itemMap[pid] = {
                        children:[],
                    }
                }
                console.log("itemMap[pid]565",itemMap[pid]);
                itemMap[pid].children.push(treeItem)
            }
        }
        return result;
    }
    console.log('第二种方式:',arrayToTree2(arr));

【第三种方式:Map+对象引用,一次for】

/**第三种办法(最优性能)
     * 思路:把数据转换Map去存储,之后遍历的同时借助对象引用,直接从Map找对应的数据做存储。
     *       (不同点在遍历的时候即做Map存储,有找对应关系。性能会更好。)
     * */
    function arrayToTree3(items) {
        const result = [];  //存放结果集
        const itemMap = {};
        for(const item of items){
            const id = item.id;
            const pid = item.pid;

            if(!itemMap[id]){
                itemMap[id] = {
                    children:[],
                }
            }
            itemMap[id] = {
                ...item,
                children:itemMap[id]['children']
            }

            const treeItem = itemMap[id];

            if(pid === 0){
                result.push(treeItem);
            }else{
                if(!itemMap[pid]){
                    itemMap[pid] = {
                        children:[],
                    }
                }
                itemMap[pid].children.push(treeItem);
            }
        }
        return result
    }
    console.log('第三种方式:',arrayToTree3(arr));

相关文章

网友评论

      本文标题:基于js的数组转换为二叉树object

      本文链接:https://www.haomeiwen.com/subject/ktfqultx.html