如何使用单个字符串键访问散列的嵌套元素?

我正在和Ruby搞砸,基本上我都有

@trans = { :links => { :quick_notes => "aaaaaaa" } } 

我想打个电话

 def t #...something end t('links.quick_notes') 

访问

 trans[:links][:quick_notes] 

我基本上试图实现与使用国际化时相同的function

 I18n.t('something.other.foo') 

我想出了这种方法

  def t(key) a='' key.to_s.split('.').each{|key| a+="[:#{key}]" } #now a == "[:links][:quick_notes]" #but I cant figure out how can I call it on @trans variable end t('links.quick_notes') 

有任何想法吗 ? 感谢名单

你可以通过inject到达那里:

 def t(key) key.to_s.split('.').inject(@trans) { |h, k| h[k.to_sym] } end 

错误检查和“没有这样的条目”检查留作练习。

对于它的价值,这里有一些显示递归使用的 manky代码。

 def getKeyChain (obj, parts) if !obj || parts.size == 0 # this is the base case obj else # this is the recursive case key = parts[0] if key.match(/^:/) key = key[1..key.size].to_sym end # each time recursing, pass a new state. # in this case, the value for the "key" and the remaining parts # that need resolving getKeyChain(obj[key], parts[1..parts.size]) end end def getCompoundKey (obj, compound) # helper makes it easier to call while not making the # recursive function more complex. getKeyChain(obj, compound.split(".")) end h0 = {:x => "hello"} h1 = {"a" => {:b => "world"}} puts getCompoundKey(h0, ":x") # => hello puts getCompoundKey(h1, "a.:b") # => world 

可以做出许多改进……“使用自己的危险”。

快乐的编码。

如果您正在寻找插入%{variable} ,包括Array支持,我一直在使用它:

 def interpolate(string, hash) string.gsub(/%\{([^\}]*)\}/).each { |match| match[/^%{(.*)}$/, 1].split('.').inject(hash) { |h, k| h[(k.to_s == k.to_i.to_s) ? k.to_i : k.to_sym] } } end 

由于Ruby 2.3 Hash有一个dig方法。 “没有这样的条目”检查是内置的:如果缺少任何键,则整个表达式返回nil 。 用法:

 @trans = { :links => { :quick_notes => "aaaaaaa" } } def t (str) syms = str.split(".").map(&:to_sym) @trans.dig(*syms) end pt('links.quick_notes') # => "aaaaaaa" 

另外一个 – 如果你有json或包含数组和哈希的哈希 – 可能是这样的:

 @trans = { :links => [ { :quick_notes => "aaaaaaa" }, { :quick_notes => "bbbbbbb" } ], :page => 1 } 

您可以在数组中包含位置测试,您可以执行此类操作。

 def t(key) key.split('.').inject(@trans) { |h,v| h.send('[]',v.to_i.to_s.eql?(v) ? v.to_i : v) } end 

这将允许您传递这样的密钥

 t('links.1.quick_notes') 

得到答案’bbbbbb’