Reputation:
I have a hash that has an array of values for each key:
h = {
'a' => ['c', 'b', 'd'],
'b' => ['c', 'b', 'f', 'g']
}
I need to return a hash g
that gives the number of "unique" values of each key in h
. For example, h['a']
has 2 values ('c'
and b'
) that are not unique in the sense that they are present in h['b']
. In that case the value of 'a'
in g
should equal 1
since 'd'
is the only unique element of h['a']
. The same goes for the key 'b'
. It has 2 common values with 'a'
in h
, but 2 unique ones as well ('f'
and g'
). So in my case the g
should equal {'a' => 1,
b=> 2}
.
I have tried h.select { |_,a| a.size == 1 }
, but it returns an empty hash.
Also, I have a way of returning the unique values but when I'm trying to write the Rspec test it fails, the solution I have is the following:
@split_log_file.each { |key, array|
"#{key} has #{array.uniq.length} unique visitors" }
Upvotes: 0
Views: 97
Reputation: 250
Below code would work with more than two keys also
h = {
'a' => ['c', 'b', 'd'],
'b' => ['c', 'b', 'f', 'g']
}
g={}
all_values = h.values.flatten
uniq_elements = all_values.select{|element| all_values.count(element) == 1 }
h.each do |k,v|
g[k] = (v & uniq_elements).count
end
g
If we don't want to check duplicates in self array of hash then we can collect uniq like below
h = { 'cat' => ['c', 'b', 'd', 'c', 'e', 'f'],
'dog' => ['c', 'b', 'f', 'g'],
'pig' => ['h', 'h', 'b', 'f'] }
g={}
all_values = h.values.collect{|val| val.uniq}.flatten
uniq_elements = all_values.select{|element| all_values.count(element) == 1 }
h.each do |k,v|
g[k] = (v & uniq_elements).count
end
g
Upvotes: 1
Reputation: 110685
This should meet your requirements.
def uniqify(h)
keys = h.keys
keys.each_with_object({}) { |k,g| g[k] =
(keys-[k]).reduce(h[k]) { |a,kk| a-h[kk] }.uniq.size } }
end
h = { 'cat' => ['c', 'b', 'e', 'f', 'c'],
'dog' => ['c', 'b', 'f', 'g', 'h'] }
uniqify h
#=> {"cat"=>1, "dog"=>2}
h = { 'cat' => ['c', 'b', 'd', 'c', 'e', 'f'],
'dog' => ['c', 'b', 'f', 'g'],
'pig' => ['h', 'h', 'b', 'f'] }
uniqify h
#=> {"cat"=>2, "dog"=>1, "pig"=>1}
See Array#-.
Upvotes: 2