扁平數據轉tree與tree數據扁平化

語言: CN / TW / HK
ead>

theme: channing-cyan highlight: a11y-dark


持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第12天,點擊查看活動詳情

扁平數據轉tree與tree數據扁平化

一、寫在前面

有時我們拿到的數據的數據結構可能不是理想的,那麼此時就要求前端程序員,具有改造數據的能力。例如拿到扁平的數據, 但我們要應用在 tree 樹形組件或 Cascader 級聯選擇器組件中,這樣的組件要求數據結構是非扁平的的具有層級遞進關係的 tree 結構。

總之就是説,提供數據的接口給到的數據,未必符合要求,而當我們又無法令他人為為我們改變時,需求和要求就來到了前端程序員這裏, 所以得具備這樣的數據處理能力。

下面是將舉兩個數據改造的例子:

一是扁平化,具有層級遞進關係的 tree 數據,轉換為扁平結構的的 flat 數據

二是反扁平化,扁平結構的 flat 數據,轉換為具有層級遞進關係的 tree 數據

二、正文部分

2.1 扁平數據轉為 tree 數據

扁平化函數

```js / * 扁平化:將具有層級遞進關係結構的 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 數據轉為扁平數據

反扁平化函數

```js / * 反扁平化:將扁平結構的 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 測試結果截圖如下:

image.png

```html

扁平數據轉tree與tree數據扁平化 Demo

扁平數據轉tree與tree數據扁平化

```

三、寫在後面

這兩個扁平化與反扁平化寫法,感覺還有值得優化的方法,但暫時想不到。

此外,遞歸的應用也是值得注意的地方。

我理解的遞歸:有條件的自己調用自己。