列表轉樹的實現思路與代碼

背景

在前端開發中,有一種組件是每一個前端都繞不過去的,樹組件。在業務中像目錄結構、組織架構、行政區域劃分這些都是典型的樹組件使用場景。通常來講,前端也就是拿來一個封裝好的控件,而後傳入符合要求的數據結構就完事了。可是,有的時候咱們拿到的東西可能並不完美,好比服務端給咱們返回了一個列表,列表中每一項之間的父子關係經過id與parentId來肯定,那麼問題來了,咱們如何在前端把這樣的列表數據轉換成樹結構的數據呢?想過麼?作過麼?作得出來麼?
我搜索了一大圈,發現絕大部分都是把代碼一貼就完事,根本不講思路是什麼,爲了能一勞永逸的解決這個問題,我以爲先把思路理清是最重要的,至於怎麼實現,就是coding的問題了,coding就看每一個人心情了,每一個人都有本身喜歡的方式,我的不建議把coding寫死,僵化。javascript

思路分析

需求是什麼?
圖片描述前端

大概是這個樣子,應該一目瞭然了。java

先說一下總體思路,根據parentId和id把數組中的每一項的父節點找到,並將本身做爲父節點的children中的一項,全部的數據項都處理完畢後,其實就差很少了,最後咱們把根節點找到並返回,轉換完成。json

執行步驟

  1. 遍歷每個列表項,對比該項(currentItem)parentId與列表內全部項的id,根據對比結果作後續處理
  2. 若是該項parentId與列表中某項(parentItem)id相等,那麼把currentItem做爲parentItem的孩子。也就是把currentItem做爲parentItem的children中的一項。
  3. 執行完上述過程後,列表中對應的父子關係就已經處理完畢了,此時咱們須要找出根節點就能夠了,判斷根節點的方法很簡單,就是parentId爲null的項。

代碼

const List = [
    {id: 1, name: 'child1', parentId: 0},
    {id: 2, name: 'child2', parentId: 0},
    {id: 6, name: 'child2_1', parentId: 2},
    {id: 0, name: 'root', parentId: null},
    {id: 5, name: 'child1_2', parentId: 1},
    {id: 4, name: 'child1_1', parentId: 1},
    {id: 3, name: 'child3', parentId: 0},
    {id: 7, name: 'child3_1', parentId: 3}
]

function ListToTree (list) {
    const copyList = list.slice(0)
    const tree = []
    for (let i = 0;i < copyList.length;i++) {
        // 找出每一項的父節點,並將其做爲父節點的children
        for (let j = 0;j < copyList.length;j++) {
            if (copyList[i].parentId === copyList[j].id) {
                if (copyList[j].children === undefined) {
                    copyList[j].children = []
                }
                copyList[j].children.push(copyList[i])
            }
        }
        // 把根節點提取出來,parentId爲null的就是根節點
        if (copyList[i].parentId === null) {
            tree.push(copyList[i])
        }
    }
    return tree
}

const tree = ListToTree(List)
console.log(JSON.stringify(tree))

上面代碼直接扔到瀏覽器中便可運行,可自行看看結果。這裏先把結果放在下面,供參考。
[{"id":0,"name":"root","parentId":null,"children":[{"id":1,"name":"child1","parentId":0,"children":[{"id":5,"name":"child1_2","parentId":1},{"id":4,"name":"child1_1","parentId":1}]},{"id":2,"name":"child2","parentId":0,"children":[{"id":6,"name":"child2_1","parentId":2}]},{"id":3,"name":"child3","parentId":0,"children":[{"id":7,"name":"child3_1","parentId":3}]}]}]
以上結果放到https://www.bejson.com/jsoned...中查看,效果更佳。數組

總結

列表轉樹的過程,我這裏用了兩層循環,而後利用了js的對象引用機制,將列表轉成了樹,其實這個過程當中已經改變了原有的列表數據結構(循環結束後打印copyList便可看到結果),因此在第一步的時候才先複製了一個列表進來。這裏應該還有可優化的地方,歡迎你們提供更多更好的思路,懇請在補充新的方案時,先把思路說清楚,切勿直接扔代碼上來。交流、溝通、理解效果纔好。瀏覽器

相關文章
相關標籤/搜索