Reputation: 431
I have an array with some elements. How can I get the number of occurrences of each element in the array?
For example, given:
a = ['cat', 'dog', 'fish', 'fish']
The result should be:
a2 #=> {'cat' => 1, 'dog' => 1, 'fish' => 2}
How can I do that?
Upvotes: 43
Views: 31427
Reputation: 1032
['cat','dog','fish','fish'].group_by(&:itself).transform_values(&:count)
=> {
"cat" => 1,
"dog" => 1,
"fish" => 2
}
Upvotes: 3
Reputation: 653
Ruby 2.7 has tally method for this.
tally → a_hash
Tallies the collection, i.e., counts the occurrences of each element. Returns a hash with the elements of the collection as keys and the corresponding counts as values.
['cat', 'dog', 'fish', 'fish'].tally
=> {"cat"=>1, "dog"=>1, "fish"=>2}
Upvotes: 16
Reputation: 65887
You can use Enumerable#group_by
to do this:
res = Hash[a.group_by {|x| x}.map {|k,v| [k,v.count]}]
#=> {"cat"=>1, "dog"=>1, "fish"=>2}
Upvotes: 44
Reputation: 291
a2 = a.reduce(Hash.new(0)) { |a, b| a[b] += 1; a }
#=> {"cat"=>1, "fish"=>2, "dog"=>1}
Upvotes: 27
Reputation: 66867
In 1.9.2 you can do it like this, from my experience quite a lot of people find each_with_object
more readable than reduce/inject
(the ones who know about it at least):
a = ['cat','dog','fish','fish']
#=> ["cat", "dog", "fish", "fish"]
a2 = a.each_with_object(Hash.new(0)) { |animal, hash| hash[animal] += 1 }
#=> {"cat"=>1, "dog"=>1, "fish"=>2}
Upvotes: 8
Reputation: 677
a = ['cat','dog','fish','fish']
a2 = Hash.new(0)
a.each do |e|
a2[e] += 1
end
a2
Upvotes: 1
Reputation: 39763
ruby fu!
count = Hash[Hash[rows.group_by{|x| x}.map {|k,v| [k, v.count]}].sort_by{|k,v| v}.reverse]
Upvotes: 0
Reputation: 15299
a = ['cat','dog','fish','fish']
a2 = Hash[a.uniq.map {|i| [i, a.count(i)]}]
Upvotes: 3
Reputation: 83680
a.inject({}){|h, e| h[e] = h[e].to_i+1; h }
#=> {"cat"=>1, "fish"=>2, "dog"=>1}
or n2 solution
a.uniq.inject({}){|h, e| h[e] = a.count(e); h }
#=> {"cat"=>1, "fish"=>2, "dog"=>1}
Upvotes: 3
Reputation: 3866
m = {}
a.each do |e|
m[e] = 0 if m[e].nil?
m[e] = m[e] + 1
end
puts m
Upvotes: 3