Hash map in ruby?

19,323

Solution 1

flat_inverse = {}
parameters["status"].each { |key, values| values.each { |v| flat_inverse[v] = key } }

flat_inverse
# {"14"=>"1", "1"=>"1", "7"=>"2", "8"=>"2", "12"=>"2", "13"=>"2"}

#or more functional
Hash[*parameters["status"].map { |k, vs| vs.zip([k] * v.length) }.flatten]

Solution 2

Couple other variants, using product:

input.map{|k,v| Hash[v.product([k])]}.inject(&:merge)
# => {"14"=>"1", "1"=>"1", "7"=>"2", "8"=>"2", "12"=>"2", "13"=>"2"} 
Hash[input.map{|k,v| v.product([k])}.flatten(1)]
# => {"14"=>"1", "1"=>"1", "7"=>"2", "8"=>"2", "12"=>"2", "13"=>"2"} 

Solution 3

input = {"1"=>["14", "1"], "2"=>["7", "8", "12", "13"]}

output = Hash[*input.map{|k,l|l.map{|v|[v,k]}}.flatten]
=> {"14"=>"1", "1"=>"1", "7"=>"2", "8"=>"2", "12"=>"2", "13"=>"2"}

output.each {|k,v| puts "#{k} -> #{v}"}
14 -> 1
1 -> 1
7 -> 2
8 -> 2
12 -> 2
13 -> 2
Share:
19,323
cjm2671
Author by

cjm2671

Founder of WikiJob, UK's largest graduate careers website. https://www.wikijob.co.uk. Founder of Linkly, https://linklyhq.com - click tracking software for marketers.

Updated on August 11, 2022

Comments

  • cjm2671
    cjm2671 over 1 year

    I'm trying to get this object, passed via AJAX:

      Parameters: {"status"=>{"1"=>["14", "1"], "2"=>["7", "8", "12", "13"]}}
    

    into something like:

    14 -> 1
    1 -> 1
    7 -> 2
    

    over which I can iterate.

    What's the most elegant way of achieving this?

  • cjm2671
    cjm2671 over 12 years
    Does this guarantee the order of the original lists is preserved?
  • Serabe
    Serabe over 12 years
    In 1.9.2 the order is preserved. If you want a data structure that preserves order, Hash (in general) is not what you are looking for. Maybe an associative array.