2017-04-07 55 views
0

我遇到了從平面陣列構建樹的問題。我正在構建一個類別 - >子類別樹,其中父類具有子類別作爲數組。Javascript遞歸樹大廈

這裏是平板式會是什麼樣子:

[ 
    { 
    "id": 1 
    }, 
    { 
    "id": 5, 
    }, 
    { 
    "id": 2, 
    "parent_id": 1 
    }, 
    { 
    "id": 3, 
    "parent_id": 1 
    }, 
    { 
    "id": 42, 
    "parent_id": 5 
    }, 
    { 
    "id": 67, 
    "parent_id": 5 
    } 
] 

而這正是我需要的結果看:

[ 
    { 
    "id":1, 
    "subcategories":[ 
     { 
     "id":2, 
     "parent_id":1 
     }, 
     { 
     "id":3, 
     "parent_id":1 
     } 
    ] 
    }, 
    { 
    "id":5, 
    "subcategories":[ 
     { 
     "id":42, 
     "parent_id":5 
     }, 
     { 
     "id":67, 
     "parent_id":5 
     } 
    ] 
    } 
] 

我試圖遞歸地做到這一點通過遞歸搜索孩子們,並將它作爲一個陣列,並繼續這樣做,直到我擊中桶的底部,但我得到一個循環結構。看來,在遍歷PARENT_ID永遠是父母的ID ...任何想法:

tree(passingInFlatObjectHere); 

function topLevel (data) { 
    let blob = []; 
    data.forEach((each) => { 
    if (!each.parent_id) { 
     blob.push(each); 
    } 
    }); 
    return blob; 
} 

function tree (data) { 
    let blob = topLevel(data).map(function (each) { 
    each.subcategories = traverse(data, each.id); 
    return each; 
    }); 
    return blob; 
} 

function traverse (data, parent_id) { 
    let blob = []; 
    if (!parent_id) { 
    return blob; 
    } 
    data.forEach((each) => { 
    if (each.id === parent_id) { 
     each.subcategories = traverse(data, each.id); 
     blob.push(each); 
    } 
    }); 
    return blob; 
} 

回答

1

我不只是想幫你解決您的問題,但也想幫助您充分利用ES6

所有topLevel功能首先可以寫成這樣:

function topLevel(data) { 
    return data.filter(node => !node.parent_id); 
} 

整潔,不是嗎?我也會建議稍微改變tree的一致性,但這當然只是風格。

function tree(data) { 
    return topLevel(data).map(each => { 
    each.subcategories = traverse(data, each.id); 
    return each; 
    }); 
} 

到目前爲止沒有邏輯問題。但是,當您檢查each.id === parent_id時,它包含一個。像這樣,這些函數搜索ID爲parent_id的節點。顯然是一個錯誤。你想要each.parent_id === parent_id

你的問題現在解決了。如果我打擾你,請停止閱讀。但你也可以利用filter這裏,並刪除多餘的略微提前退出和重寫你的函數:

function traverse(data, parentId) { 
    const children = data.filter(each => each.parent_id === parentId); 
    children.forEach(child => { 
    child.subcategories = traverse(data, child.id); 
    }); 
    return children; 
} 
+0

哇感謝您的幫助和展示我所有的漂亮的新糖ES6。 – Goodwin