我有一个哈希如下:
hash = {"Monday" => "a", "Tuesday" => "b", "Wednesday" => "c", "Thursday" => "b", "Friday" => "c"}
我想获得一个新的哈希:
{"a" => "Monday", "b" => "Tuesday, Thursday" , "c" => "Wednesday, Friday"}
Hash#invert
只给出第一个值并丢失重复值。有效的方法吗?
答案 0 :(得分:3)
hash.inject({}){ |h, (k,v)| (h[v] ||= []) << k; h }
=> {"a"=>["Monday"], "b"=>["Tuesday", "Thursday"], "c"=>["Wednesday", "Friday"]}
答案 1 :(得分:2)
result = hash.inject({}){|m, kv| m[kv.last] ||= []; m[kv.last] << kv.first; m}
这将为您提供以下形式的哈希:
{"a" => ["Monday"], "b" => ["Tuesday", "Thursday"] , "c" => ["Wednesday", "Friday"] }
如果您绝对需要它们作为逗号分隔列表,您可以在以后加入它们:
result = Hash(*result.map{|k, v| [k, v.join(', ')]})
或者在第一次迭代时附加它们:
result = hash.inject({}) do |m, kv|
if m[kv.last]
m[kv.last] << ", "
else
m[kv.last] = ""
end
m[kv.last] << kv.first
m
end
答案 2 :(得分:0)
使用来自Facets的几个抽象的功能方法:
require 'facets'
hash.map_by { |k, v| [v, k] }.mash { |k, vs| [k, vs.join(", ")] }
#=> {"a"=>["Monday"], "b"=>["Tuesday", "Thursday"], "c"=>["Wednesday", "Friday"]}
答案 3 :(得分:0)
each_with_object
是一种替代方法,不确定我是否可以某种方式摆脱三元组。 。
hash.each_with_object({}) { |kv,new_hash| k,v = kv; new_hash[v] = new_hash[v] ? new_hash[v] + ',' + k : k}
=> {"a"=>"Monday", "b"=>"Tuesday,Thursday", "c"=>"Wednesday,Friday"}