cjm2671
cjm2671

Reputation: 19496

Hash map in ruby?

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?

Upvotes: 2

Views: 19343

Answers (3)

Matt
Matt

Reputation: 17649

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]

Upvotes: 6

Mladen Jablanović
Mladen Jablanović

Reputation: 44110

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"} 

Upvotes: 5

Lars Haugseth
Lars Haugseth

Reputation: 14881

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

Upvotes: 1

Related Questions