Reputation: 8461
I have an array and it looks like this: [7, 2, 3, 2, 2, 1]
. As you can see there are three elements in this array with the integer value of 2. I want to take this array and create an index that will look something like this: { 1 => 1, 2 => 3, 3 => 1, 4 => 0, 5 => 0, 6 => 0, 7 => 1 }
So, basically a bar chart/histogram/index of a how many duplicates there are in the array.
Just for a high level view of this. I'm trying to find all of the unique emails for each account within my application.
Upvotes: 1
Views: 109
Reputation: 54223
This variant should be much faster than the other answers and will work for any array :
def histogram(array)
array.each_with_object( Hash.new(0) ){|number, count| count[number] += 1 }
end
array = [7, 2, 3, 2, 2, 1, 'a', 'b', 'c', 'b']
p freq = histogram(array)
#=> {7=>1, 2=>3, 3=>1, 1=>1, "a"=>1, "b"=>2, "c"=>1}
p array.select{|number| freq[number] == 1}
#=> [7, 3, 1, "a", "c"]
If I understand your question correctly, you don't need the 4 => 0, 5 => 0, 6 => 0
part in your Hash if all you want to do is to find elements that only appear once.
The information is here if you want to get it, though :
p freq[6]
#=> 0
If your array comes from a database via ActiveRecord, it might be a better idea to find the unique elements directly with a SQL query instead of retrieving all elements and applying logic to it.
Upvotes: 1
Reputation: 110665
arr = [8, 3, 4, 3, 3, 2]
min, max = arr.minmax
#=> [2, 8]
arr.each_with_object((min..max).to_a.product([0]).to_h) { |n,h| h[n] += 1 }
#=> {2=>1, 3=>3, 4=>1, 5=>0, 6=>0, 7=>0, 8=>1}
Note:
(min..max).to_a.product([0]).to_h
#=> {2=>0, 3=>0, 4=>0, 5=>0, 6=>0, 7=>0, 8=>0}
Upvotes: 0
Reputation: 52357
a = [7, 2, 3, 2, 2, 1]
1.upto(a.max).each_with_object({}) {|number, hash| hash[number] = a.count(number)}
#=> {1=>1, 2=>3, 3=>1, 4=>0, 5=>0, 6=>0, 7=>1}
Upvotes: 3