如何在Ruby中构建双嵌套哈希?

时间:2017-04-16 19:32:53

标签: ruby ruby-hash

我正在研究一个语言翻译系统,需要建立一个如何翻译要翻译的字段的“地图”。首先,我需要使用一组默认值构建数据结构。

假设我有这些变量:

fields = [:title, :description]
languages = [:en, :fr]

我正在尝试找到一种最简单的方法来创建一个如下所示的哈希:

{
  :detection => {
    :title => {
      :en => :en,
      :fr => :fr
    },
    :description => {
      :en => :en,
      :fr => :fr
    }
  },
  # ... other fields
}

我知道我可以通过迭代fields变量来实现这一点,并在其中,使用Ruby的zip方法构建内部哈希值。然而,我不知道的是,是否有办法从这两个字段中“双拉”外部和内部值。像{ :detection => fields.zip(languages.zip(languages)) }之类的东西(我知道这不是使用zip的正确方法,但这就是我追求的想法。)

同样,我可以通过fields循环来做到这一点,但我很好奇我能不能这样做吗?

谢谢!

以下是它当前的实现方式(循环):

 def build_default_detection_data
   fields = [:title, :description]
   languages = [:en, :fr]

   default = {
     detection_map: {},
   }

   fields.each do |field|
     default[:detection_map][field] = Hash[languages.zip(languages)]
   end

   default
 end

1 个答案:

答案 0 :(得分:0)

我不确定我是否理解这个问题,但这是我解释的答案。

keys      = [:detection, :abstraction]
fields    = [:title, :description]
languages = [:en, :fr]

keys.each_with_object({}) do |key, g|
  g.update(
    key => fields.each_with_object({}) do |f, h| 
      h[f] = languages.each_with_object({}) { |sym, h| h[sym] = sym } 
    end
  )
end

#=> {
#     :detection => { 
#       :title => {
#         :en => :en, 
#         :fr => :fr
#       }, 
#       :description => {
#         :en => :en, 
#         :fr => :fr
#       }
#     },
#     :abstraction => {
#       :title => {
#         :en => :en, 
#         :fr => :fr
#       }, 
#       :description => {
#         :en => :en, 
#         :fr => :fr
#       }
#     }
#   }