2011-09-22 190 views
2

我试图让这个对象,通过AJAX传递:红宝石哈希图?

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

成类似:

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

了,我可以迭代。

达到此目的最优雅的方式是什么?

+2

这样的区别是什么? http://stackoverflow.com/questions/7513730/hash-invert-in-ruby – fl00r

回答

6
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] 
+0

这是否保证原始列表的顺序被保留? – cjm2671

+1

在1.9.2中保存顺序。如果你想要一个保存顺序的数据结构,哈希(通常)不是你正在寻找的。也许是一个关联数组。 – Serabe

1
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 
5

情侣其他变体,使用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"}