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