2014-07-17 61 views
2

結帳這個多維散列:獲取父多維散列

hash = { 
     A: { 
      name: 'A', children: {} 
     }, 
     B: { 
      name: 'B', children: { 
       B1: { 
        name: 'B1', children: { 
         B1i: { 
          name: 'B1i', children: {} 
         }, 
         B1ii: { 
          name: 'B1ii', children: {} 
         }, 
         B1iii: { 
          name: 'B1iii', children: {} 
         }, 
         B1iv: { 
          name: 'B1iv', children: {} 
         } 
        }, 
       }, 
      }, 
     }, 
     C: { 
      name: 'C', children: { 
       C1: { 
        name: 'C1', children: {} 
       }, 
       C2: { 
        name: 'C2', children: {} 
       } 
      }, 
     },     
    } 

def is_a_child_of(parent, child) 
    child.parent[:name] == parent ? true : false 
end 

hash.each do |key, f1| 
    puts "F1 generation member: #{f1[:name]}" 

    f1[:children].each do |key, f2| 

     is_a_child_of('B2', f2)    

     puts "F2 generation member: #{f2[:name]}" 

     f2[:children].each do |key, f3| 
      puts "F3 generation member: #{f3[:name]}" 
     end 
    end 
end #=> 
# 
# F1 generation member: A 
# F1 generation member: B 
# F2 generation member: B1 
# F3 generation member: B1i 
# F3 generation member: B1ii 
# F3 generation member: B1iii 
# F3 generation member: B1iv 
# F1 generation member: C 
# F2 generation member: C1 
# F2 generation member: C2 
# 

什麼是找出每個「個人的」父母最高效方式?這裏有一個我希望使用的真理方法:

def is_a_child_of(parent, child) 
    child.parent[:name] == parent ? true : false 
end 

但是,child.parent是完整的僞代碼。我怎麼能實現這個父方法?

或者,它會更efficient簡單地登錄每個循環中的父項?更多的僞代碼:

hash.each_with_parent do |parent, key, value| 
end 

我怎麼能實現這個each_with_parent循環?

將一個選項保存在每個散列中的父母?

例如

B: { 
     name: 'B', children: { 
      B1: { 
       name: 'B1', parent: 'B', children: {} 
      } 
     } 
    } 
+0

'parent.values.any? {| v | v ==孩子}'? –

+0

@UriAgassi我敢打賭這是效率最低的方法。 – mudasobwa

+0

@mudasobwa - 好的,那麼'parent.values.any? {| v | v.equal?孩子}' –

回答

3

您需要實現某種樹結構,其中的子節點會跟蹤其父項。

這是一個簡單的實現,跟蹤孩子父母的樹:

class Tree < Hash 
    def initialize(hash = {}) 
    replace build_tree(hash) 
    end 

    private 

    def build_tree(hash, parent: :root) 
    hash.inject({}) do |h,(k,v)| 
     h[k] = { 
     parent: parent, 
     value: v.kind_of?(Hash) ? build_tree(v, parent: k) : v 
     }; h 
    end 
    end 
end 

require 'yaml' 
puts Tree.new({ 
    A: { 
    A1: 'asdf', 
    A2: 'qwer' 
    }, 
    B: { 
    B1: { 
     B1i: 'uiop', 
     B1ii: 'zxcv' 
    } 
    } 
}).to_yaml 

--- !ruby/hash:Tree 
:A: 
    :parent: :root 
    :value: 
    :A1: 
     :parent: :A 
     :value: asdf 
    :A2: 
     :parent: :A 
     :value: qwer 
:B: 
    :parent: :root 
    :value: 
    :B1: 
     :parent: :B 
     :value: 
     :B1i: 
      :parent: :B1 
      :value: uiop 
     :B1ii: 
      :parent: :B1 
      :value: zxcv 

TL; DR:這gem尋找你的使用情況非常穩固。

3

每個哈希不知道它的存在的背景下,任何東西。一種方法是搜索整個結構的孩子,記住,你發現它,然後用它來尋找父母。另一種是,如你所說,將父母存儲在每個記錄中。哪一個最適合你,取決於你有多少條記錄,你想用多少額外空間來記錄明確的父母,以及你想花費多少時間來尋找父母的數據結構。

您可能想要查看一些圖庫以瞭解如何存儲這種數據結構。