我有一个包含若干元素的数组,如何获取每个元素在数组中出现的次数?
例如,已知以下数组:
a = ['cat', 'dog', 'fish', 'fish']
结果应该是:
a2 #=> {'cat' => 1, 'dog' => 1, 'fish' => 2}
我该怎么做?
您可以使用Enumerable#group_by
来实现此功能:
res = Hash[a.group_by {|x| x}.map {|k,v| [k,v.count]}]
#=> {"cat"=>1, "dog"=>1, "fish"=>2}
a2 = a.reduce(Hash.new(0)) { |a, b| a[b] += 1; a }
#=> {"cat"=>1, "fish"=>2, "dog"=>1}
Ruby 2.7新增了tally方法。
tally → a_hash
该方法可以对集合进行计数,即统计每个元素出现的次数。返回一个哈希表,其中集合中的元素作为键,相应的计数作为值。
['cat', 'dog', 'fish', 'fish'].tally
=> {"cat"=>1, "dog"=>1, "fish"=>2}
a2 = {}
a.uniq.each{|e| a2[e]= a.count(e)}
在1.9.2中,你可以像这样做。从我的经验来看,相当多的人发现each_with_object
比reduce/inject
更易读(至少了解它的人):
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}
m = {}
a.each do |e|
m[e] = 0 if m[e].nil?
m[e] = m[e] + 1
end
puts m
a.inject({}){|h, e| h[e] = h[e].to_i+1; h }
#=> {"cat"=>1, "fish"=>2, "dog"=>1}
a.uniq.inject({}){|h, e| h[e] = a.count(e); h }
#=> {"cat"=>1, "fish"=>2, "dog"=>1}
a = ['cat','dog','fish','fish']
a2 = Hash[a.uniq.map {|i| [i, a.count(i)]}]
['cat','dog','fish','fish'].group_by(&:itself).transform_values(&:count)
=> {
"cat" => 1,
"dog" => 1,
"fish" => 2
}