js將列表組裝成樹結(jié)構(gòu)的兩種實現(xiàn)方式分享
前言
工作中偶爾就會遇到后端同學丟來一個列表,要我們自己組裝成一個樹結(jié)構(gòu)渲染到頁面上,本文以兩種不同方式探索生成樹的算法思想。

背景介紹
可組裝成樹結(jié)構(gòu)的數(shù)組一般有以下幾個要素:
- 當前節(jié)點id
- parentId 當前節(jié)點的父節(jié)點id
- children 子節(jié)點列表(可能不會在接口中返回,需要組裝時候自己加上)
原始結(jié)構(gòu):

目標結(jié)構(gòu):

關(guān)鍵就是一維數(shù)組中通過parentId找到其對應的父節(jié)點并添加到父節(jié)點的children數(shù)組中。
實現(xiàn)方案
最直接的方式就是遍歷數(shù)組,并把找到的子節(jié)點逐一添加到父節(jié)點中
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é)點
res.push(item);
}
});
return res;
}考慮進一步優(yōu)化,使用哈希表,以id為key存儲每個節(jié)點值,省去data.find計算
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) {
// * 當前項有父節(jié)點
parent.children = parent.children || [];
parent.children.push(item);
} else {
// * 當前項沒有父節(jié)點 -> 頂層
parentList.push(item);
}
});
return parentList;
}即便數(shù)據(jù)量很小,帶來的性能提升也是顯著的

遞歸法
更有騷操作遞歸法,性能會很差,但代碼會很酷??
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ù)量稍微大一點……

(上面遞歸,下面非遞歸)
資源
原始數(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)的兩種實現(xiàn)方式的文章就介紹到這了,更多相關(guān)js列表組裝成樹結(jié)構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript的創(chuàng)建多行字符串的7種方法
多行字符串的作用是用來提高源代碼的可讀性.尤其是當你處理預定義好的較長字符串時,把這種字符串分成多行書寫更有助于提高代碼的可讀性和可維護性.在一些語言中,多行字符串還可以用來做代碼注釋. 大部分動態(tài)腳本語言都支持多行字符串,比如Python, Ruby, PHP. 但Javascript呢?2014-04-04
layui使用數(shù)據(jù)表格實現(xiàn)購物車功能
這篇文章主要為大家詳細介紹了layui使用數(shù)據(jù)表格實現(xiàn)購物車功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07
解決function函數(shù)內(nèi)的循環(huán)變量
鼠標放到指定的行上自動彈出當前的個數(shù),從0開始,這個功能方便我們在tab切換中定位2008-10-10
uniapp自定義多列瀑布流組件項目實戰(zhàn)總結(jié)
這篇文章主要為大家介紹了uniapp自定義多列瀑布流組件實戰(zhàn)總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09

