JavaScript數(shù)組扁平轉(zhuǎn)樹(shù)形結(jié)構(gòu)數(shù)據(jù)(Tree)的實(shí)現(xiàn)
前言
之前面試有遇到過(guò)這個(gè)問(wèn)題,面試官問(wèn):如何把一個(gè)數(shù)組數(shù)據(jù)扁平,然后轉(zhuǎn)化為Tree結(jié)構(gòu)數(shù)據(jù),工作中剛好也用到了,在這里總結(jié)一下。
需求大致如下
把這個(gè)數(shù)組轉(zhuǎn)為樹(shù)形結(jié)構(gòu)數(shù)據(jù)(Tree)
const flatArr = [
{ id: '01', parentId: 0, name: '節(jié)點(diǎn)1' },
{ id: '011', parentId: '01', name: '節(jié)點(diǎn)1-1' },
{ id: '0111', parentId: '011', name: '節(jié)點(diǎn)1-1-1' },
{ id: '02', parentId: 0, name: '節(jié)點(diǎn)2' },
{ id: '022', parentId: '02', name: '節(jié)點(diǎn)2-2' },
{ id: '023', parentId: '02', name: '節(jié)點(diǎn)2-3' },
{ id: '0222', parentId: '022', name: '節(jié)點(diǎn)2-2-2' },
{ id: '03', parentId: 0, name: '節(jié)點(diǎn)3' },
]最終結(jié)果
[
{
id: '01',
name: '節(jié)點(diǎn)1',
parentId: 0,
children: [
{
id: '011',
name: '節(jié)點(diǎn)1-1',
parentId: '01',
children: [
{
id: '0111',
name: '節(jié)點(diǎn)1-1-1',
parentId: '011',
children: [
...
],
},
],
},
],
},
{
id: '02',
name: '節(jié)點(diǎn)2',
parentId: 0,
children: [
// 如上節(jié)點(diǎn)1
]
},
{
id: '03',
name: '節(jié)點(diǎn)3',
parentId: 0,
children: [
// 如上節(jié)點(diǎn)1
]
}
]遞歸方式
遞歸方式實(shí)現(xiàn)是OK的,但是數(shù)據(jù)多的話會(huì)稍微慢一點(diǎn)哈
const flatArr = [
{ id: '01', parentId: 0, name: '節(jié)點(diǎn)1' },
{ id: '011', parentId: '01', name: '節(jié)點(diǎn)1-1' },
{ id: '0111', parentId: '011', name: '節(jié)點(diǎn)1-1-1' },
{ id: '02', parentId: 0, name: '節(jié)點(diǎn)2' },
{ id: '022', parentId: '02', name: '節(jié)點(diǎn)2-2' },
{ id: '023', parentId: '02', name: '節(jié)點(diǎn)2-3' },
{ id: '0222', parentId: '022', name: '節(jié)點(diǎn)2-2-2' },
{ id: '03', parentId: 0, name: '節(jié)點(diǎn)3' },
]
function getTreeData (arr, parentId) {
function loop (parentId) {
return arr.reduce((pre, cur) => {
if (cur.parentId === parentId) {
cur.children = loop(cur.id)
pre.push(cur)
}
return pre
}, [])
}
return loop(parentId)
}
const result = getTreeData(flatArr, 0)
console.log('result', result)打印結(jié)果如圖

非遞歸方式
這種方法看起來(lái)就很簡(jiǎn)單代碼也很簡(jiǎn)潔
const flatArr = [
{ id: '01', parentId: 0, name: '節(jié)點(diǎn)1' },
{ id: '011', parentId: '01', name: '節(jié)點(diǎn)1-1' },
{ id: '0111', parentId: '011', name: '節(jié)點(diǎn)1-1-1' },
{ id: '02', parentId: 0, name: '節(jié)點(diǎn)2' },
{ id: '022', parentId: '02', name: '節(jié)點(diǎn)2-2' },
{ id: '023', parentId: '02', name: '節(jié)點(diǎn)2-3' },
{ id: '0222', parentId: '022', name: '節(jié)點(diǎn)2-2-2' },
{ id: '03', parentId: 0, name: '節(jié)點(diǎn)3' },
]
function getData (arr) {
// 利用兩層filter實(shí)現(xiàn)
let data = arr.filter(item => {
item.children = arr.filter(e => {
return item.id === e.parentId
})
return !item.parentId
})
return data
}
const res = getData(flatArr)
console.log('res', res)打印結(jié)果如圖

小結(jié)
實(shí)現(xiàn)的方法很多,選擇自己喜歡的就好,到此這篇關(guān)于JavaScript數(shù)組扁平轉(zhuǎn)樹(shù)形結(jié)構(gòu)數(shù)據(jù)(Tree)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)JavaScript數(shù)組扁平轉(zhuǎn)樹(shù)形結(jié)構(gòu) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript樹(shù)形結(jié)構(gòu)數(shù)組處理之遞歸問(wèn)題
- JS前端二維數(shù)組生成樹(shù)形結(jié)構(gòu)示例詳解
- JS實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)與數(shù)組結(jié)構(gòu)相互轉(zhuǎn)換并在樹(shù)形結(jié)構(gòu)中查找對(duì)象
- JavaScript平鋪數(shù)組轉(zhuǎn)樹(shù)形結(jié)構(gòu)的實(shí)現(xiàn)示例
- 如何將JavaScript將數(shù)組轉(zhuǎn)為樹(shù)形結(jié)構(gòu)
- JavaScript 實(shí)現(xiàn)普通數(shù)組數(shù)據(jù)轉(zhuǎn)化為樹(shù)形數(shù)據(jù)結(jié)構(gòu)的步驟說(shuō)明
相關(guān)文章
JS實(shí)現(xiàn)左右拖動(dòng)改變內(nèi)容顯示區(qū)域大小的方法
這篇文章主要介紹了JS實(shí)現(xiàn)左右拖動(dòng)改變內(nèi)容顯示區(qū)域大小的方法,涉及JavaScript實(shí)時(shí)響應(yīng)鼠標(biāo)事件動(dòng)態(tài)改變頁(yè)面元素屬性的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
Three.js利用性能插件stats實(shí)現(xiàn)性能監(jiān)聽(tīng)的方法
Three.js 是一款運(yùn)行在瀏覽器中的 3D 引擎,你可以用它創(chuàng)建各種三維場(chǎng)景,而下面這篇文章主要給大家介紹了關(guān)于Three.js如何利用性能插件stats實(shí)現(xiàn)性能監(jiān)聽(tīng)的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09
微信小程序使用this.setData()遇到的問(wèn)題及解決方案詳解
this.setData估計(jì)是小程序中最經(jīng)常用到的一個(gè)方法,但是要注意其實(shí)他是有限制的,忽略這些限制的話,會(huì)導(dǎo)致數(shù)據(jù)無(wú)法更新,下面這篇文章主要給大家介紹了關(guān)于微信小程序使用this.setData()遇到的問(wèn)題及解決方案,需要的朋友可以參考下2022-08-08
教你一步步實(shí)現(xiàn)一個(gè)簡(jiǎn)易promise
Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案回調(diào)函數(shù)和事件更合理且更強(qiáng)大,這篇文章主要給大家介紹了關(guān)于如何一步步實(shí)現(xiàn)一個(gè)簡(jiǎn)易promise的相關(guān)資料,需要的朋友可以參考下2021-11-11
JavaScript日期工具類DateUtils定義與用法示例
這篇文章主要介紹了JavaScript日期工具類DateUtils定義與用法,涉及javascript針對(duì)日期時(shí)間的獲取、轉(zhuǎn)換、比較、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下2018-09-09

