2015-02-07 69 views
1

我有一個哈希散列,我需要把它變成方法,他們的關鍵是方法的名稱,值是方法返回,但有額外的要求,如果一個值也是一個散列值,整個值被返回。紅寶石 - 哈希方法遞歸

例如:

hash = {:a => 1, :b => 2, :c => { :a => 1, :b => 2, :c => 3} } 
hash.c.a #=> 1 
hash.c #=> { :a => 1, :b => 2, :c => 3} 

我怎麼能做到這一點?幫助讚賞。

回答

3

您可以使用OpenStruct來製作這樣的數據結構。例如:

require 'ostruct' 
s = OpenStruct.new(a: 1, b: 2, c: OpenStruct.new(a: 1, b: 2, c: 3)) 
s.c.a # => 1 
s.c # => #<OpenStruct a=1, b=2, c=3> 
+0

如果我有一個100級以上的散列,我該如何迭代散列? – user2840647 2015-02-07 19:15:57

+1

這是一個不同的問題。你可以發表另一個問題,但你需要確保你所問的問題是清楚的。例如,在這裏,您有興趣在散列'hash.c'中檢索':a'的值,而不是在散列'hash'中檢索':a'的值。 (你顯然不能在同一個類中使用兩個同名的方法。)當嵌套中多次出現同一個鍵時,如何擴展到嵌套散列並不十分清楚。 – 2015-02-07 21:29:46

0

另一種選擇是使用Hashie。 Hashie是一組散列式擴展。其中包括可以直接訪問的字段 - 特別參見Mash選項:

mash = Hashie :: Mash.new(:a => 1,:b => 2,:c => Hashie :: Mash.new(:A => 1時,:b => 2,C => 3))

0

作爲你的接收機是散列,必須定義的類Hash方法:

def makem(h) 
    h.each do |k,v| 
    case v 
    when Hash 
     Hash.instance_eval { define_method(k.to_s) { v } } 
     v.each { |kk,vv| Hash.instance_eval { define_method(kk.to_s) { vv } } } 
    end 
    end 
end 

讓我們試試吧:

h = {:a => 1, :b => 2, :c => { :a => 1, :b => 2, :d => 3 } } 

makem(h) 
Hash.instance_methods(false).select { |m| m.size == 1 } 
    #=> [:c, :a, :b, :d] 
h.c 
    #=> {:a=>1, :b=>2, :d=>3} 
h.c.a 
    #=> 1 
h.c.b 
    #=> 2 
h.c.d 
    #=> 3 

在你的榜樣,您有:

:c => { :a => 1, :b => 2, :c => 3} 

如果你想有一個方法c返回上面的哈希,你顯然不能定義,將返回3同名的另一種方法。

您可能希望重新考慮定義這些方法的可取性。也許在你的課堂上構建諸如def m(hash, key)等方法會更有用。