js將列表組裝成樹結(jié)構(gòu)的兩種實(shí)現(xiàn)方式分享
前言
工作中偶爾就會(huì)遇到后端同學(xué)丟來一個(gè)列表,要我們自己組裝成一個(gè)樹結(jié)構(gòu)渲染到頁面上,本文以兩種不同方式探索生成樹的算法思想。
背景介紹
可組裝成樹結(jié)構(gòu)的數(shù)組一般有以下幾個(gè)要素:
- 當(dāng)前節(jié)點(diǎn)id
- parentId 當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)id
- children 子節(jié)點(diǎn)列表(可能不會(huì)在接口中返回,需要組裝時(shí)候自己加上)
原始結(jié)構(gòu):
目標(biāo)結(jié)構(gòu):
關(guān)鍵就是一維數(shù)組中通過parentId找到其對(duì)應(yīng)的父節(jié)點(diǎn)并添加到父節(jié)點(diǎn)的children數(shù)組中。
實(shí)現(xiàn)方案
最直接的方式就是遍歷數(shù)組,并把找到的子節(jié)點(diǎn)逐一添加到父節(jié)點(diǎn)中
function listToTreeSimple(data) { const res = []; data.forEach((item) => { const parent = data.find((node) => node.id === item.parentId); if (parent) { parent.children = parent.children || []; parent.children.push(item); } else { // * 根節(jié)點(diǎn) res.push(item); } }); return res; }
考慮進(jìn)一步優(yōu)化,使用哈希表,以id為key存儲(chǔ)每個(gè)節(jié)點(diǎn)值,省去data.find計(jì)算
function listToTree(data) { // * 先生成parent建立父子關(guān)系 const obj = {}; data.forEach((item) => { obj[item.id] = item; }); // * obj -> {1001: {id: 1001, parentId: 0, name: 'AA'}, 1002: {...}} // console.log(obj, "obj") const parentList = []; data.forEach((item) => { const parent = obj[item.parentId]; if (parent) { // * 當(dāng)前項(xiàng)有父節(jié)點(diǎn) parent.children = parent.children || []; parent.children.push(item); } else { // * 當(dāng)前項(xiàng)沒有父節(jié)點(diǎn) -> 頂層 parentList.push(item); } }); return parentList; }
即便數(shù)據(jù)量很小,帶來的性能提升也是顯著的
遞歸法
更有騷操作遞歸法,性能會(huì)很差,但代碼會(huì)很酷??
function recursiveToTree(data) { function loop(key) { const arr = []; data.forEach((item) => { if (item.parentId === key) { item.children = loop(item.id); arr.push(item); } }); return res; } return loop(1); }
看看性能,誒?看起來竟然遞歸性能最佳??
但是數(shù)據(jù)量稍微大一點(diǎn)……
(上面遞歸,下面非遞歸)
資源
原始數(shù)據(jù)列表
const list = [ { id: 1001, parentId: 0, name: "AA", }, { id: 1002, parentId: 1001, name: "BB", }, { id: 1003, parentId: 1001, name: "CC", }, { id: 1004, parentId: 1003, name: "DD", }, { id: 1005, parentId: 1003, name: "EE", }, { id: 1006, parentId: 1002, name: "FF", }, { id: 1007, parentId: 1002, name: "GG", }, { id: 1008, parentId: 1004, name: "HH", }, { id: 1009, parentId: 1005, name: "II", }, ];
總結(jié)
到此這篇關(guān)于js將列表組裝成樹結(jié)構(gòu)的兩種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)js列表組裝成樹結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript的創(chuàng)建多行字符串的7種方法
多行字符串的作用是用來提高源代碼的可讀性.尤其是當(dāng)你處理預(yù)定義好的較長字符串時(shí),把這種字符串分成多行書寫更有助于提高代碼的可讀性和可維護(hù)性.在一些語言中,多行字符串還可以用來做代碼注釋. 大部分動(dòng)態(tài)腳本語言都支持多行字符串,比如Python, Ruby, PHP. 但Javascript呢?2014-04-04layui使用數(shù)據(jù)表格實(shí)現(xiàn)購物車功能
這篇文章主要為大家詳細(xì)介紹了layui使用數(shù)據(jù)表格實(shí)現(xiàn)購物車功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07解決function函數(shù)內(nèi)的循環(huán)變量
鼠標(biāo)放到指定的行上自動(dòng)彈出當(dāng)前的個(gè)數(shù),從0開始,這個(gè)功能方便我們?cè)趖ab切換中定位2008-10-10JavaScript實(shí)現(xiàn)新年倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)新年倒計(jì)時(shí)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11JS實(shí)現(xiàn)的郵箱提示補(bǔ)全效果示例
這篇文章主要介紹了JS實(shí)現(xiàn)的郵箱提示補(bǔ)全效果,涉及javascript正則匹配、事件響應(yīng)及頁面元素動(dòng)態(tài)操作相關(guān)技巧,需要的朋友可以參考下2018-01-01uniapp自定義多列瀑布流組件項(xiàng)目實(shí)戰(zhàn)總結(jié)
這篇文章主要為大家介紹了uniapp自定義多列瀑布流組件實(shí)戰(zhàn)總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09