在平常開發工做中,咱們常常碰到將線性的數據轉換成樹的需求,今天給你們分享一個簡單的轉換算法。javascript
下面是咱們轉換前的數據:java
[
{
"id":1,
"parent_id":0,
"name":"四川省"
},
{
"id":2,
"parent_id":0,
"name":"廣東省"
},
{
"id":3,
"parent_id":0,
"name":"江西省"
},
{
"id":5,
"parent_id":1,
"name":"成都市"
},
{
"id":6,
"parent_id":5,
"name":"錦江區"
},
{
"id":7,
"parent_id":6,
"name":"九眼橋"
},
{
"id":8,
"parent_id":6,
"name":"蘭桂坊"
},
{
"id":9,
"parent_id":2,
"name":"東莞市"
},
{
"id":10,
"parent_id":9,
"name":"長安鎮"
},
{
"id":11,
"parent_id":3,
"name":"南昌市"
}
]
複製代碼
咱們轉換後的結果是:算法
[
{
"id":1,
"parent_id":0,
"name":"四川省",
"children":[
{
"id":5,
"parent_id":1,
"name":"成都市",
"children":[
{
"id":6,
"parent_id":5,
"name":"錦江區",
"children":[
{
"id":7,
"parent_id":6,
"name":"九眼橋"
},
{
"id":8,
"parent_id":6,
"name":"蘭桂坊"
}
]
}
]
}
]
},
{
"id":2,
"parent_id":0,
"name":"廣東省",
"children":[
{
"id":9,
"parent_id":2,
"name":"東莞市",
"children":[
{
"id":10,
"parent_id":9,
"name":"長安鎮"
}
]
}
]
},
{
"id":3,
"parent_id":0,
"name":"江西省",
"children":[
{
"id":11,
"parent_id":3,
"name":"南昌市"
}
]
}
]
複製代碼
let array = [
{
id: 1,
parent_id: 0,
name: "四川省"
},
{
id: 2,
parent_id: 0,
name: "廣東省"
},
{
id: 3,
parent_id: 0,
name: "江西省"
},
{
id: 5,
parent_id: 1,
name: "成都市"
},
{
id: 6,
parent_id: 5,
name: "錦江區"
},
{
id: 7,
parent_id: 6,
name: "九眼橋"
},
{
id: 8,
parent_id: 6,
name: "蘭桂坊"
},
{
id: 9,
parent_id: 2,
name: "東莞市"
},
{
id: 10,
parent_id: 9,
name: "長安鎮"
},
{
id: 11,
parent_id: 3,
name: "南昌市"
}
]
function listToTree(list) {
let map = {};
list.forEach(item => {
if (! map[item.id]) {
map[item.id] = item;
}
});
list.forEach(item => {
if (item.parent_id !== 0) {
map[item.parent_id].children ? map[item.parent_id].children.push(item) : map[item.parent_id].children = [item];
}
});
return list.filter(item => {
if (item.parent_id === 0) {
return item;
}
})
}
console.log(listToTree(array));
複製代碼
這段代碼的核心就在 listToTree
方法中,這個方法分爲了三個部分:json
第一部分先將數組中的全部元素都複製到 map
中(注意:這裏是引用複製哦,這個細節很重要)。數組
執行第二次遍歷前的 map:bash
// map
{
...,
"3":{
"id":3,
"parent_id":0,
"name":"江西省"
},
...
}
複製代碼
而後這個時候遍歷 parent_id
不等於 0
的元素:數據結構
[
...,
{
id: 11,
parent_id: 3,
name: "南昌市"
},
...
]
複製代碼
而後發現南昌市有 parent_id
,咱們再給 map[item.parent_id]
設置子元素,經過南昌市的 parent_id
能夠推導出:ui
map["3"].children ? map["3"].children.push(item) : map[3].children = [item];
複製代碼
上面的代碼判斷了是否存在 children
,若是不存在則直接給它賦值,不然將值 push
到 children
中。spa
執行完第二步後,咱們已經把子節點添加到了它的父節點上,可是咱們並無刪除掉以前的子節點。因此第三部就是對數據進行過濾,只要父節點便可。code
須要注意的是,咱們一直都是對 map 進行操做的,可是結果怎麼到了 list 上呢,這就是上面提到的引用複製。