2013-07-07 208 views
2

對不起,令人困惑的標題......我不知道更好的總結。我有一個對象數組。其中一些對象具有對其父對象的引用。類似的東西:從對象數組創建一個對象引用父對象

data: 
[ 
    {id: 2, parent: 1}, 
    {id: 1}, 
    {id: 3, parent: 1}, 
    {id: 5, parent: 3}, 
    {id: 4, parent: 3}, 
    {id: 6, parent: 2} 

] 

我想要做的是創建一個對象出這個數組,其中的子對象嵌套在他們的父母。像這樣:

data: { 
    id: 1, 
    children: [ 
    { 
     id:2, 
     children: [ 
     {id: 6} 
     ] 
    }, 
    { 
     id:3, 
     children: [ 
     {id: 4}, 
     {id: 5} 
     ] 
    } 
    ] 
} 

有沒有人知道這樣做的聰明方式? 我知道我必須通過這個數組的每個對象來檢查是否有父。但我怎樣才能真正創造這個對象?

回答

2

不確定這是做到這一點的最佳方式,但至少它是一種方法。

  1. 首先遍歷所有的節點:
    • 被放在一個查找表中的節點的idnodes)。
    • 找到root節點(沒有parent的單節點)。
  2. 二回路(與查找表完成):
    • 檢查是否nodeparent(存在於除root每個節點)。
    • 通過在查找表中查找id獲取parent節點。
    • 獲取parent.children數組,或創建它,如果它還不存在。
    • 將此node添加到該陣列。
    • 刪除此nodeparent財產。

注意這改變了你的data對象的原始節點對象。這是有意的,因爲樹是通過存儲對父節點中其他節點的引用來構建的。如果您需要保留原始節點data不變,則應在構建查找表時克隆節點對象。例如,您可以在查找forEach循環(使用jQuery時)中添加node = $.extend({}, node);作爲第一行。

下面是一個實現和demonstration

var data = [ 
    {id: 2, parent: 1}, 
    {id: 1}, 
    {id: 3, parent: 1}, 
    {id: 5, parent: 3}, 
    {id: 4, parent: 3}, 
    {id: 6, parent: 2} 
]; 

// Node lookup table 
var nodes = {}; 
// Root node 
var root = null; 
// Fill lookup table and find root 
data.forEach(function(node) { 
    nodes[node.id] = node; 
    // Assuming only one root node 
    if(!("parent" in node)) { 
     root = node; 
    } 
}); 
// Build tree 
for(var id in nodes) { 
    var node = nodes[id]; 
    if("parent" in node) { 
     // Add to children of parent 
     var parent = nodes[node.parent]; 
     (parent.children = parent.children || []).push(node); 
     // Remove parent property (optional) 
     delete node.parent; 
    } 
} 
console.log(JSON.stringify(root));