算法-無限分類遞歸

做爲前端, 不用算法也能夠寫成項目. 可是若是明白會算法的話, 你寫起代碼來會更駕輕就熟.
無限分類遞歸 多數用在樹形結構數據. 有這樣一組數據:
const arr = [
    {
        id: 4,
        name: '張三的兒子',
        parentId: 1
    },
    {
        id: 43,
        name: '張三的2兒子',
        parentId: 1
    },
    {
        id: 5,
        name: '李四的兒子',
        parentId: 2
    },
    {
        id: 6,
        name: '張三的兒子的兒子',
        parentId: 4
    },
    {
        id: 1,
        name: '張三',
        parentId: 0
    },
    {
        id: 2,
        name: '李四',
        parentId: 0
    },
    {
        id: 3,
        name: '王五',
        parentId: 0
    },
];

想要獲得的結果是這樣子的:前端

const result = [
    {
        id: 1,
        name: '張三',
        parentId: 0,
        children: [
            {
                id: 4,
                name: '張三的兒子',
                parentId: 1,
                children: [
                    {
                        id: 6,
                        name: '張三的兒子的兒子',
                        parentId: 4
                    }
                ]
            },
            {
                id: 43,
                name: '張三的2兒子',
                parentId: 1
            }
        ]
    },
    {
        id: 2,
        name: '李四',
        parentId: 0,
        children: [
            {
                id: 5,
                name: '李四的兒子',
                parentId: 2
            }
        ]
    },
    {
        id: 3,
        name: '王五',
        parentId: 0
    }
];

這裏我有兩種作法:算法

  1. 遞歸
  2. 充分利用數據的引用(堆棧)

第一種:code

function rescurve(arr, id) {
    let treeData = [];
    arr.forEach(i => {
        if(i.parentId == id) {
            treeData.push(i);
            i.children = rescurve(arr, i.id);
        }
    });
    return treeData;
};
console.log(rescurve(arr, 0)); // 輸出正確的值

這種方法沒什麼說的 就是執行自身遞歸出想要的結構.對象

第二種:遞歸

function setTreeData(arr) {
    let map = {}; // 構建map
    arr.forEach(i => {
        map[i.id] = i; // 構建以id爲鍵 當前數據爲值
    });

    let treeData = [];
    arr.forEach(child => {
        const mapItem = map[child.parentId]; // 獲取當前數據的parentId是否存在map中

        if (mapItem) { // 存在則表示當前數據不是最頂層數據
        
            // 注意: 這裏的map中的數據是引用了arr的它的指向仍是arr, 當mapItem改變時arr也會改變
            (mapItem.children || ( mapItem.children = [] )).push(child); // 這裏判斷mapItem中是否存在children, 存在則插入當前數據, 不存在則賦值children爲[]而後再插入當前數據
        } else { // 不存在則是組頂層數據
            treeData.push(child);
        }
    });

    return treeData;
};

console.log(setTreeData(arr)); // 輸出正確的值

這裏須要注意的是對象的引用, 利用對象的引用改變指向的arr的數據. 就獲得想要的結構io

相關文章
相關標籤/搜索