0

I'm working on a language translation system and need to build a "map" of how the fields to translate should be translated. To start, I need to build the data structure with a set of defaults.

Let's say I have these variables:

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

I'm trying to find the most simple way to create a hash that looks like this:

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

I know that I can do this by iterating over the fields variable and within that, build the inner hash values by using Ruby's zip method. What I don't know, however, is if there's a way to "double zip" up the outer and inner values from those two fields. Something like { :detection => fields.zip(languages.zip(languages)) } (I know that this isn't the right way to use zip but that's the idea I'm after).

Again, I can do this with a loop over fields but I'm curious if I can do this differently?

Thanks!


Here's how it's currently implemented (with looping):

 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
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Dan Sharp
  • 1,209
  • 2
  • 12
  • 31

1 Answers1

0

I'm not sure I understand the question, but here's an answer to my interpretation.

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
#       }
#     }
#   } 
Oleksandr Holubenko
  • 4,310
  • 2
  • 14
  • 28
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100