• Js扁平化和tree数据结构转换


    数据

    let 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: 3},
    ]
    
    let tree = [
        {
            "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": []
                       }
                    ]
                }
            ]
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    tree扁平化

    1. 递归实现
      遍历tree,每一项加进结果集,如果有children且长度不为0,则递归遍历。
    function treeToArray(tree) {
      let res = []
      for (const item of tree) {
        const { children, ...i } = item
        if (children && children.length) {
          res = res.concat(treeToArray(children))
        }
        res.push(i)
      }
      return res
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. reduce实现
    function treeToArray(tree) {
      return tree.reduce((res, item) => {
        const { children, ...i } = item
        return res.concat(i, children && children.length ? treeToArray(children) : [])
      }, [])
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    扁平化数组转tree

    1. 递归实现
      最常用到的就是递归实现,思路也比较简单,实现一个方法,该方法传入tree父节点和父id,循环遍历数组,无脑查询,找到对应的子节点,push到父节点中,再递归查找子节点的子节点。
    function arrayToTree(items) {
      let res = []
      let getChildren = (res, pid) => {
          for (const i of items) {
              if (i.pid === pid) {
                  const newItem = { ...i, children: [] }
                  res.push(newItem)
                  getChildren(newItem.children, newItem.id)
              }
          }
      }
      getChildren(res, 0)
      return res
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. map对象实现
      先转map再找对应关系
    function arrayToTree(items) {
        let res = [] // 存放结果集
        let map = {}
    
        // 先转成map存储
        for (const i of items) {
            map[i.id] = { ...i, children: [] }
        }
    
        for (const i of items) {
            const newItem = map[i.id]
            if (i.pid === 0) {
                res.push(newItem)
            } else {
                if (Object.prototype.hasOwnProperty.call(map, i.pid)) {
                    map[i.pid].children.push(newItem)
                }
            }
        }
        return res
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意: Object.prototype.hasOwnProperty: 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性,会忽略掉那些从原型链上继承到的属性。

    function arrayToTree(items) {
        let res = [] // 存放结果集
        let map = {}
        // 判断对象是否有某个属性
        let getHasOwnProperty = (obj, property) => Object.prototype.hasOwnProperty.call(obj, property)
    
        // 边做map存储,边找对应关系
        for (const i of items) {
            map[i.id] = {
                ...i,
                children: getHasOwnProperty(map, i.id) ? map[i.id].children : []
            }
            const newItem = map[i.id]
            if (i.pid === 0) {
                res.push(newItem)
            } else {
                if (!getHasOwnProperty(map, i.pid)) {
                    map[i.pid] = {
                        children: []
                    }
                }
                map[i.pid].children.push(newItem)
            }
        }
        return res
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    CAPL学习之路-DoIP相关函数
    Hudi从内核到实战介绍
    nvm下载node指定版本后npm不存在
    innovus:antenna设置
    Java:Java与Python——顶级编程语言比较
    华为OD机试 - 二维伞的雨滴效应(Java & JS & Python)
    金融服务行业SaaS项目管理系统解决方案,助力企业挖掘更广阔的增长服务空间
    9.9校招 实习 内推 面经
    【linux命令讲解大全】113.网络接口和系统设备监测工具ifstat和iostat的使用
    【Web前端大作业】基于HTML+CSS+JavaScript制作西北大学新闻网站(7页)
  • 原文地址:https://blog.csdn.net/MoXinXueWEB/article/details/127819052