温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JavaScript扁平数据转tree与tree数据扁平化的方法

发布时间:2022-06-14 09:50:08 来源:亿速云 阅读:119 作者:zzz 栏目:开发技术

这篇文章主要介绍“JavaScript扁平数据转tree与tree数据扁平化的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript扁平数据转tree与tree数据扁平化的方法”文章能帮助大家解决问题。

    一、写在前面

    有时我们拿到的数据的数据结构可能不是理想的,那么此时就要求前端程序员,具有改造数据的能力。例如拿到扁平的数据, 但我们要应用在 tree 树形组件或 Cascader 级联选择器组件中,这样的组件要求数据结构是非扁平的的具有层级递进关系的 tree 结构。

    总之就是说,提供数据的接口给到的数据,未必符合要求,而当我们又无法令他人为为我们改变时,需求和要求就来到了前端程序员这里, 所以得具备这样的数据处理能力。

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

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

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

    二、正文部分

    2.1 扁平数据转为 tree 数据

    扁平化函数

      /**
       * 扁平化:将具有层级递进关系结构的 tree 数据扁平化
       * 
       * @param treeList 有层级递进关系结构的 tree 数据
       * @param flatList 用于接收扁平化结果的变量
       * @returns {*} 返回扁平化结果
       */
      function treeToFlat (treeList, flatList) {
        // flatList.length > 9999 是考虑底线保护原则,出于极限保护的目的设置的,可不设或按需设置。
        if (flatList.length > 9999) {
          return
        }
        treeList.map(e => {
          flatList.push(e)
          // 递归:有条件的自己调用自己,条件是 e.children.length 为真
          if (e.children && e.children.length) {
            treeToFlat(e.children, flatList)
          }
        })
        // console.log('扁平化后:', flatList)
        return flatList
      }

    2.2 tree 数据转为扁平数据

    反扁平化函数

      /**
       * 反扁平化:将扁平结构的 flat 数据转换为具有层级递进关系结构的 tree 数据
       * 
       * @param flatList 扁平结构的数据
       * @param treeList 用于接收反扁平化结果的变量
       * @returns {*} 返回反扁平化结果
       */
      function flatToTree (flatList, treeList) {
        flatList.map(e => {
          // 以 e.pid===null,作为判断是不是根节点的依据,或者直接写死根节点(如果确定的话),
          // 具体以什么作为判断根节点的依据,得看数据的设计规则,通常是判断层级或是否代表根节点的标记
          if (e.pid === null) {
            // 避免出现重复数据
            const index = treeList.findIndex(sub => sub.id === e.id)
            if (index === -1) {
              treeList.push(e)
            }
          }
          flatList.map(e2 => {
            if (e2.pid === e.id) {
              // 避免出现重复数据
              const index = e.children.findIndex(sub => sub.id === e2.id)
              if (index === -1) {
                e.children.push(e2)
              }
            }
          })
        })

    2.3 完整测试 demo

    demo 测试结果截图如下:

    JavaScript扁平数据转tree与tree数据扁平化的方法

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>扁平数据转tree与tree数据扁平化 Demo</title>
    </head>
    <body>
    <h2>扁平数据转tree与tree数据扁平化</h2>
    <script>
      window.onload = function () {
        test()
      }
      function test () {
        let flatList = [],
          treeList = [
            {
              id: 1,
              pid: null,
              label: '第一层',
              value: '1',
              children: [
                {
                  id: 2,
                  pid: 1,
                  label: '第二层1',
                  value: '2.1',
                  children: []
                },
                {
                  id: 3,
                  pid: 1,
                  label: '第二层2',
                  value: '2.2',
                  children: []
                },
                {
                  id: 4,
                  pid: 1,
                  label: '第二层3',
                  value: '2.3',
                  children: [
                    {
                      id: 5,
                      pid: 4,
                      label: '第三层1',
                      value: '3.1',
                      children: []
                    },
                    {
                      id: 6,
                      pid: 4,
                      label: '第三层2',
                      value: '3.2',
                      children: []
                    },
                  ]
                },
              ]
            }
          ]
        console.log('原始 tree 数据:', JSON.parse(JSON.stringify(treeList)))
        // 扁平化
        console.log('tree =>flat,扁平化后:', treeToFlat(JSON.parse(JSON.stringify(treeList)), flatList))
        // 反扁平化,SON.parse(JSON.stringify()) 为了实现深拷贝
        console.log('flat =>tree,反扁平化后:', flatToTree(JSON.parse(JSON.stringify(flatList)), treeList))
      }
      /**
       * 扁平化:将具有层级递进关系结构的 tree 数据扁平化
       * 
       * @param treeList 有层级递进关系结构的 tree 数据
       * @param flatList 用于接收扁平化结果的变量
       * @returns {*} 返回扁平化结果
       */
      function treeToFlat (treeList, flatList) {
        // flatList.length > 9999 是考虑底线保护原则,出于极限保护的目的设置的,可不设或按需设置。
        if (flatList.length > 9999) {
          return
        }
        treeList.map(e => {
          flatList.push(e)
          // 递归:有条件的自己调用自己,条件是 e.children.length 为真
          if (e.children && e.children.length) {
            treeToFlat(e.children, flatList)
          }
        })
        // console.log('扁平化后:', flatList)
        return flatList
      }
      /**
       * 反扁平化:将扁平结构的 flat 数据转换为具有层级递进关系结构的 tree 数据
       * 
       * @param flatList 扁平结构的数据
       * @param treeList 用于接收反扁平化结果的变量
       * @returns {*} 返回反扁平化结果
       */
      function flatToTree (flatList, treeList) {
        flatList.map(e => {
          // 以 e.pid===null,作为判断是不是根节点的依据,或者直接写死根节点(如果确定的话),
          // 具体以什么作为判断根节点的依据,得看数据的设计规则,通常是判断层级或是否代表根节点的标记
          if (e.pid === null) {
            // 避免出现重复数据
            const index = treeList.findIndex(sub => sub.id === e.id)
            if (index === -1) {
              treeList.push(e)
            }
          }
          flatList.map(e2 => {
            if (e2.pid === e.id) {
              // 避免出现重复数据
              const index = e.children.findIndex(sub => sub.id === e2.id)
              if (index === -1) {
                e.children.push(e2)
              }
            }
          })
        })
        // console.log('反扁平化后:', treeList)
        return treeList
      }
    </script>
    </body>
    </html>

    关于“JavaScript扁平数据转tree与tree数据扁平化的方法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注亿速云行业资讯频道,小编每天都会为大家更新不同的知识点。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI