需求
源數據
let srcList = ['動物-昆蟲-螞蟻', '動物-昆蟲', '植物-草-綠色', '植物-花-紅色','植物-花-黃色']
- 去重分類
- 構建樹形數據如下
[
{
"name": "動物",
"children": [
{
"name": "昆蟲",
"children": [
{
"name": "螞蟻"
}
]
}
]
},
{
"name": "植物",
"children": [
{
"name": "草",
"children": [
{
"name": "綠色"
}
]
},
{
"name": "花",
"children": [
{
"name": "紅色"
},
{
"name": "黃色"
}
]
}
]
}
]
思路
- 避免多根將每一條分類信息路徑,視爲容器數組內的元素
- 使用固定指針記錄目標根位置,遊標指針匹配節點,移動
- 新增節點之前判斷是否有同名節點存在,存在則進入其下層子節點
- 進入新增節點域,須判斷當前節點是否爲葉子節點,是則裁剪該子節點指向
- 每輪路徑信息匹配,需重置遊標指針於根位置
解法
function listToTree(srcList) {
// 1.記錄根位置
let destList = []
srcList.forEach(path => {
// 2.待匹配項
let pathList = path.split('-')
// 3.將移動指針重置頂層,確保每次從根檢索匹配(必須!!!)
let levelList = destList
// 4.遍歷待詢節點
for (let name of pathList) {
// 5.同層同名節點查找匹配
let obj = levelList.find(item => item.name == name)
// 6.若不存在則建立該節點
if (!obj) {
obj = { name, children: [] }
levelList.push(obj)
// 7.若當前被增節點是葉子節點,則裁剪該節點子節點屬性
if (name == pathList[pathList.length - 1]) {
delete obj.children
}
}
// 8.已有則進入下一層,繼續尋找
levelList = obj.children
}
})
return destList
}
測試
let srcList = ['動物-昆蟲-螞蟻', '動物-昆蟲', '植物-草-綠色', '植物-花-紅色','植物-花-黃色']
let result = listToTree(srcList)
console.log(JSON.stringify(result, null, 2))