溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript扁平數據轉tree與tree數據扁平化的方法

發(fā)布時間:2022-06-14 09:50:08 來源:億速云 閱讀:115 作者:zzz 欄目:開發(fā)技術

這篇文章主要介紹“JavaScript扁平數據轉tree與tree數據扁平化的方法”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“JavaScript扁平數據轉tree與tree數據扁平化的方法”文章能幫助大家解決問題。

    一、寫在前面

    有時我們拿到的數據的數據結構可能不是理想的,那么此時就要求前端程序員,具有改造數據的能力。例如拿到扁平的數據, 但我們要應用在 tree 樹形組件或 Cascader 級聯(lián)選擇器組件中,這樣的組件要求數據結構是非扁平的的具有層級遞進關系的 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,作為判斷是不是根節(jié)點的依據,或者直接寫死根節(jié)點(如果確定的話),
          // 具體以什么作為判斷根節(jié)點的依據,得看數據的設計規(guī)則,通常是判斷層級或是否代表根節(jié)點的標記
          if (e.pid === null) {
            // 避免出現(xiàn)重復數據
            const index = treeList.findIndex(sub => sub.id === e.id)
            if (index === -1) {
              treeList.push(e)
            }
          }
          flatList.map(e2 => {
            if (e2.pid === e.id) {
              // 避免出現(xiàn)重復數據
              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()) 為了實現(xiàn)深拷貝
        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,作為判斷是不是根節(jié)點的依據,或者直接寫死根節(jié)點(如果確定的話),
          // 具體以什么作為判斷根節(jié)點的依據,得看數據的設計規(guī)則,通常是判斷層級或是否代表根節(jié)點的標記
          if (e.pid === null) {
            // 避免出現(xiàn)重復數據
            const index = treeList.findIndex(sub => sub.id === e.id)
            if (index === -1) {
              treeList.push(e)
            }
          }
          flatList.map(e2 => {
            if (e2.pid === e.id) {
              // 避免出現(xiàn)重復數據
              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數據扁平化的方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識,可以關注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI