2014-04-15 106 views
1

我有一個關聯列表,我從關係數據庫構建到Rails 4項目的JSON對象中。它看起來像將單個級別的JSON鄰接列表轉換爲嵌套的JSON樹

{ 
    "6": { 
     "children": [ 
      8, 
      10, 
      11 
     ] 
    }, 
    "8": { 
     "children": [ 
      9, 
      23, 
      24 
     ] 
    }, 
    "9": { 
     "children": [ 
      7 
     ] 
    }, 
    "10": { 
     "children": [ 
      12, 
      14 
     ] 
    ... 
} 

現在我想進入一個JSON結構由jsTree消耗,看起來像

{ 
    id: "6", 
    children: [ 
      { id: "8", children: [ { id: "9", children: [{id: "7"}] }] 
      { id: "10", children: [ { id: "12",...} {id: "14",...} ] } 
...and so on 
} 

的問題,我用的樹是建立這種面對這回溯嵌套級別的JSON的問題。算法教科書中的示例不足以與我的經驗相匹配,在這種情況下,回溯問題只需通過將某些元素數據(如數字或字符串)推送到堆棧來處理。

任何幫助建立這樣一棵樹的實用方法是讚賞。

+0

爲什麼不使用將分層結構添加到AR模型(​​如acts_as_tree或ancestry或awesome_nested_set)的gem? –

+0

@MarkThomas是的,儘可能讓我的生活變得更輕鬆,我正在研究一個已經在這些線上開發的應用程序。 – anomit

回答

1

假設有一個根元素(因爲它是一個樹)可以用很短的遞歸方法來構建樹:

def process(id, src) 
    hash = src[id] 
    return { id: id } if hash.nil? 
    children = hash['children'] 
    { id: id, children: children.map { |child_id| process(child_id.to_s, src) } } 
end 

# the 'list' argument is the hash you posted, '6' is the key of the root node 
json = process('6', list) 

# json value: 
# 
# {:id=>"6", :children=>[ 
# {:id=>"8", :children=>[ 
#  {:id=>"9", :children=>[ 
#  {:id=>"7"}]}, 
#  {:id=>"23"}, 
#  {:id=>"24"}]}, 
# {:id=>"10", :children=>[ 
#  {:id=>"12"}, 
#  {:id=>"14"}]}, 
# {:id=>"11"}]} 

我加入了return { id: id } if hash.nil?行,因爲你的輸入哈希不包含的條目對於兒童7,11,12,14,23,24。如果他們的輸入如下所示,則可以移除該線。

"7" => { "children" => [] }, 
"11" => { "children" => [] }, 
"12" => { "children" => [] }, 
"14" => { "children" => [] }, 
"23" => { "children" => [] }, 
"24" => { "children" => [] } 

在這種情況下,該方法會產生,而不是{:id=>"7"},你可以,如果你想通過包括children.empty?檢查,在這種情況下,只有一個:id鍵返回哈希(就像我在hash.nil?做改變檢查)。但是,就一致性而言,我可能傾向於將children鍵以空數組作爲值存在,而不是完全省略它。