ruby - Swapping keys and values in a hash -
in ruby, how swap keys , values on hash?
let's have following hash:
{:a=>:one, :b=>:two, :c=>:three} that want transform into:
{:one=>:a, :two=>:b, :three=>:c} using map seems rather tedious. there shorter solution?
ruby has helper method hash lets treat hash if inverted.
{a: 1, b: 2, c: 3}.key(1) => :a if want keep inverted hash, hash#invert should work situations.
{a: 1, b: 2, c: 3}.invert => {1=>:a, 2=>:b, 3=>:c} but...
if have duplicate values, invert discarding last of values. likewise key return first match.
{a: 1, b: 2, c: 2}.key(2) => :b {a: 1, b: 2, c: 2}.invert => {1=>:a, 2=>:c} so.. if values unique can use hash#invert if not, can keep values array, this:
class hash # invert not lossy # {"one"=>1,"two"=>2, "1"=>1, "2"=>2}.inverse => {1=>["one", "1"], 2=>["two", "2"]} def safe_invert each_with_object({}) |(key,value),out| out[value] ||= [] out[value] << key end end end note: code tests here.
or in short...
class hash def safe_invert self.each_with_object({}){|(k,v),o|(o[v]||=[])<<k} end end
Comments
Post a Comment