扁平資料轉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資料扁平化

```

三、寫在後面

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

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

我理解的遞迴:有條件的自己呼叫自己。