Reputation: 4251
I got a hash in following format:
{"A"=> 0, "B"=> 0, "C"=> 1, "D"=> 3, "E"=> 0}
And I want to have this hash with no duplicate value pairs. For instance, desired output is:
{ "A"=> 0, "C"=>1, "D"=>3 }
Upvotes: 1
Views: 351
Reputation: 1963
convert to Array, use uniq
and convert back to Hash:
Hash[some_hash.to_a.uniq(&:last)]
invert keys and values and invert back:
some_hash.invert.invert
use set
:
require 'set'
set = Set.new
some_hash.select{ |_,v| !set.include?(v).tap{ set << v } }
Pay attention #1/#3 takes first elements while #2 takes the last ones
h = {a: 0, b: 1, c: 0, d: 2, e: 1}
Hash[h.to_a.uniq(&:last)] # {a: 0, b: 1, d: 2}
h.invert.invert # {c: 0, d: 2, e: 1}
Benchmark ('a'..'zzz' hash)
user system total real
#1 0.040000 0.010000 0.050000 ( 0.040964)
#2 0.010000 0.000000 0.010000 ( 0.002194)
#3 0.010000 0.000000 0.010000 ( 0.010814)
Upvotes: 3
Reputation: 52357
You could do something like this:
h = {"A"=> 0, "B"=> 0, "C"=> 1, "D"=> 3, "E"=> 0}
arr = []
h.each {|k,v| arr.include?(v) ? h.delete(k) : arr << v }
#=> {"A"=>0, "C"=>1, "D"=>3}
Upvotes: 2