摘要:執行步驟遍歷每一個列表項,對比該項與列表內所有項的,根據對比結果做后續處理如果該項與列表中某項相等,那么把作為的孩子。這里應該還有可優化的地方,歡迎大家提供更多更好的思路,懇請在補充新的方案時,先把思路說清楚,切勿直接扔代碼上來。
背景
在前端開發中,有一種組件是每個前端都繞不過去的,樹組件。在業務中像目錄結構、組織架構、行政區域劃分這些都是典型的樹組件使用場景。一般來說,前端也就是拿來一個封裝好的控件,然后傳入符合要求的數據結構就完事了。但是,有的時候我們拿到的東西可能并不完美,比如服務端給我們返回了一個列表,列表中每一項之間的父子關系通過id與parentId來確定,那么問題來了,我們如何在前端把這樣的列表數據轉換成樹結構的數據呢?想過么?做過么?做得出來么?
我搜索了一大圈,發現絕大部分都是把代碼一貼就完事,根本不講思路是什么,為了能一勞永逸的解決這個問題,我覺得先把思路理清是最重要的,至于怎么實現,就是coding的問題了,coding就看每個人心情了,每個人都有自己喜歡的方式,個人不建議把coding寫死,僵化。
需求是什么?
大概是這個樣子,應該一目了然了。
先說一下整體思路,根據parentId和id把數組中的每一項的父節點找到,并將自己作為父節點的children中的一項,所有的數據項都處理完畢后,其實就差不多了,最后我們把根節點找到并返回,轉換完成。
執行步驟遍歷每一個列表項,對比該項(currentItem)parentId與列表內所有項的id,根據對比結果做后續處理
如果該項parentId與列表中某項(parentItem)id相等,那么把currentItem作為parentItem的孩子。也就是把currentItem作為parentItem的children中的一項。
執行完上述過程后,列表中對應的父子關系就已經處理完畢了,此時我們需要找出根節點就可以了,判斷根節點的方法很簡單,就是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即可看到結果),所以在第一步的時候才先復制了一個列表進來。這里應該還有可優化的地方,歡迎大家提供更多更好的思路,懇請在補充新的方案時,先把思路說清楚,切勿直接扔代碼上來。交流、溝通、理解效果才好。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95383.html
摘要:背景之前寫了一篇列表轉樹的文章,有列表轉樹的需求自然就會有樹轉列表的需求,這里我把樹轉列表的思路與代碼再整理一下。總結樹轉列表過程中,我這里的深度優先采用了遞歸方式,可能會對內存占用較多,使用時請自行權衡。 背景 之前寫了一篇列表轉樹的文章,有列表轉樹的需求自然就會有樹轉列表的需求,這里我把樹轉列表的思路與代碼再整理一下。 思路分析 需求是什么?老規矩,上圖showImg(https:...
摘要:當變量指向一個對象的時候,實際指向的是存儲地址測試結果數組轉樹的方式節點節點節點節點節點節點節點節點將作為鍵值方便二次遍歷做索引為的是根節點這樣只要遍歷倆次第一次遍歷將數組轉節點對象,存儲到新的對象里,為鍵值方便索引第二次遍歷根據索引插入子 當變量指向一個對象的時候,實際指向的是存儲地址測試: a = {val: 123} b = a b.val = 321 ...
摘要:由于目前還未開發樹形表格組件,也參閱了網絡上部分基于表格封裝的開源樹形組件,都沒有找的太理想可進行二次開發的開源項目,所以就萌生了自行開發樹形表格。 由于ElementUI目前還未開發樹形表格組件,也參閱了網絡上部分基于ElementUI表格封裝的開源樹形組件,都沒有找的太理想可進行二次開發的開源項目,所以就萌生了自行開發樹形表格。 本示例提供開發思路,移除了多余的樣式,比較適合新手入...
摘要:樹中結點的最大層次稱為樹的深度或高度。二叉樹有深度遍歷和廣度遍歷,深度遍歷有前序中序和后序三種遍歷方法。二叉樹的前序遍歷可以用來顯示目錄結構等中序遍歷可以實現表達式樹,在編譯器底層很有用后序遍歷可以用來實現計算目錄內的文件及其信息等。 樹的簡介 棧、隊列、鏈表等數據結構,都是順序數據結構。而樹是非順序數據結構。樹型結構是一類非常重要的非線性結構。直觀地,樹型結構是以分支關系定義的層次結...
摘要:列表的第二個元素的本身是一個表示左子樹的列表。子樹具有根節點和兩個表示葉節點的空列表。重要的是要記住這種表示的是左右子樹引用的是其他二叉樹的實例。為了完成一個簡單的二叉樹數據結構的定義,我們寫出訪問參見左右子節點和根值的方法。 嵌套列表表示樹 在用嵌套列表表示樹時,我們使用 Python 的列表來編寫這些函數。雖然把界面寫成列表的一系列方法與我們已實現其他的抽象數據類型有些不同,但這樣...
閱讀 1523·2021-09-22 15:35
閱讀 2005·2021-09-14 18:04
閱讀 876·2019-08-30 15:55
閱讀 2449·2019-08-30 15:53
閱讀 2680·2019-08-30 12:45
閱讀 1203·2019-08-29 17:01
閱讀 2577·2019-08-29 15:30
閱讀 3514·2019-08-29 15:09