2017-04-07 104 views
0

我面臨將簡單平面數據轉換爲層次結構的常見問題。我發現有關多個主題,但仍然不能得到如何平數據轉換正好給我必要的分層格式將平面數據轉換爲具有內部對象的層次結構javascript

這是我的JSON

[ 
    { 
    "id": 1, 
    "name": "Sponsor", 
    "description": null, 
    "parentId": null 
    }, 
    { 
    "id": 2, 
    "name": "Class", 
    "description": null, 
    "parentId": 1 
    }, 
    { 
    "id": 3, 
    "name": "Study", 
    "description": null, 
    "parentId": 2 
    }, 
    { 
    "id": 4, 
    "name": "Site", 
    "description": null, 
    "parentId": 3 
    } 
] 

,我需要得到格式這樣

[ 
    { 
     "data":{ 
     "id": 1, 
     "name":"Sponsor", 
     "description":null, 
     "parentId":"null" 
     }, 
     "children":[ 
     { 
      "data":{ 
      "id": 2, 
      "name":"Class", 
      "description":null, 
      "parentId":"1" 
      }, 
      "children":[ 
      { 
       "data":{ 
       "id": 3, 
       "name":"Study", 
       "description":null, 
       "parentId":"2" 
       }, 
      "children": [ 
       { 
        "data":{ 
        "id": 4, 
        "name":"Site", 
        "description":null, 
        "parentId":"3" 
        } 
       } 
       ] 
      } 
      ] 
     } 
     ] 
    } 
    ] 

這是我的功能

flatToHierarchy(flat) { 

    let roots = []; 
    let all = {}; 

    flat.forEach(function (item) { 
     all[item.id] = item 
    }); 

    Object.keys(all).forEach(function (id) { 
     let item = all[id]; 
     if (item.parentId === null) { 
     roots.push(item) 
     } else if (item.parentId in all) { 
     let p = all[item.parentId]; 
     if (!('Children' in p)) { 
      p.children = [] 
     } 
     p.children.push(item) 
     } 
    }); 

    console.log(roots); 
    return roots 
    } 

輸出

[ 
    { 
    "id": 1, 
    "name": "Sponsor", 
    "description": null, 
    "parentId": null, 
    "children": [ 
     { 
     "id": 2, 
     "name": "Class", 
     "description": "Together", 
     "parentId": 1, 
     "children": [ 
      { 
      "id": 3, 
      "name": "Study", 
      "description": "browsing data", 
      "parentId": 2, 
      "children": [ 
       { 
       "id": 4, 
       "name": "Site", 
       "description": null, 
       "parentId": 3, 
       "children": [] 
       } 
      ] 
      } 
     ] 
     } 
    ] 
    } 
    ] 

我很接近渴望的結果。有人能幫我解決這個問題嗎?

編輯

通過@ Someone3 提供正確的答案,這是稍微修改代碼爲我的需求

flatToHierarchy (flat) { 

    let roots = []; 
    let all = {}; 
    let ids = []; 

    flat.forEach(function (item) { 
     let itemId = item.id; 
     let convertedItem = function (id) { 
     let newItem = {}; 
     newItem['data'] = id; 
     return newItem; 
     } ; 
     all[itemId] = convertedItem(item); 
     ids.push(itemId); 
    }); 

    for (let i = 0; i < ids.length; i++) { 
     let id = ids[i]; 
     let convertedItem = all[id]; 
     let parentId = convertedItem.data.parentId; 

     if (parentId === null) { 
     roots.push(convertedItem); 
     } else if (parentId in all) { 
     let p = all[parentId]; 
     if (!('children' in p)) { 
      p.children = [] 
     } 
     p.children.push(convertedItem) 
     } 
    } 
    return roots 
    } 
+0

您所需的格式與您的json不一樣。在你的示例格式中,每個對象都有一個不同的父對象,所以它們不能在同一個子對象中:[array] – Theo

+0

'flat.forEach(parent => parent.children = flat.filter(child => child.parentId = == parent.id))' – Thomas

+0

和''Children'!=='children'' – Thomas

回答

1

下面的代碼是適合自己情況的全部源代碼。我修改並添加了幾行代碼。 請注意,此代碼假定父母總是在他們的孩子之前插入此樹。如果這個假設並不總是如此,那麼你的代碼需要改變更多。

let flatData = [ 
    { 
    "id": 1, 
    "name": "Sponsor", 
    "description": null, 
    "parentId": null 
    }, 
    { 
    "id": 2, 
    "name": "Class", 
    "description": null, 
    "parentId": 1 
    }, 
    { 
    "id": 3, 
    "name": "Study", 
    "description": null, 
    "parentId": 2 
    }, 
    { 
    "id": 4, 
    "name": "Site", 
    "description": null, 
    "parentId": 3 
    } 
]; 

function convertItem(item) { 
    let newItem = {}; 
    newItem.data = item; 
    return newItem; 
} 

function flatToHierarchy(flat) { 

    let roots = []; 
    let all = {}; 
    let ids = []; 

    flat.forEach(function (item) { 
     let itemId = item.id; 
     let convertedItem = convertItem(item); 
     all[itemId] = convertedItem; 
     ids.push(itemId); 
    }); 

    // We use ids array instead of object to maintain its previous order. 
    for (let i = 0; i < ids.length; i++) { 
     let id = ids[i]; 
     let convertedItem = all[id]; 
     let parentId = convertedItem.data.parentId; 

     if (parentId === null) { 
     delete convertedItem.data.parentId; 
     delete convertedItem.data.id; 
     roots.push(convertedItem); 
     } else if (parentId in all) { 
     let p = all[parentId]; 
     if (!('Children' in p)) { 
      p.children = [] 
     } 
     delete convertedItem.data.parentId; 
     delete convertedItem.data.id; 
     p.children.push(convertedItem) 
     } 
    }; 

    console.log(roots); 
    return roots 
    } 

    flatToHierarchy(flatData); 

我們可以在推送前分解兩個刪除。

+0

非常感謝您的幫助。我接受了你的答案,因爲它對我有很大的幫助,但我稍微修改了它以適合我的代碼 – antonyboom

相關問題