js 將線性數據轉爲樹形

在平常開發工做中,咱們常常碰到將線性的數據轉換成樹的需求,今天給你們分享一個簡單的轉換算法。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,若是不存在則直接給它賦值,不然將值 pushchildren 中。spa

執行完第二步後,咱們已經把子節點添加到了它的父節點上,可是咱們並無刪除掉以前的子節點。因此第三部就是對數據進行過濾,只要父節點便可。code

總結

須要注意的是,咱們一直都是對 map 進行操做的,可是結果怎麼到了 list 上呢,這就是上面提到的引用複製。

相關文章
相關標籤/搜索