我有一个巨大的数组,列出了创建对象的星期几,所以我最终得到了一个类似于以下内容的数组:
["wednesday", "thursday", "friday"]
,但它包含250,000个元素。
我想要的是一个新的哈希,它将匹配键并增加值,所以结果如下:
{"wednesday": 250, "thursday": 600, "saturday": 120}
我如何才能实现这一结果?
这是我目前的代码:
days = []
Invitation.all.each do |invitation|
day = invitation.created_at.strftime("%A")
days.push(day)
end
days
答案 0 :(得分:6)
你可以这样做:
Invitation.all.reduce(Hash.new(0)) do |memo, invitation|
memo[invitation.created_at.strftime("%A")] += 1
memo
end
Hash.new(0)
生成一个默认值为0的哈希值。这是一种从数组中获取计数的通用方法
答案 1 :(得分:4)
array = ["wednesday", "thursday", "friday", "wednesday", "wednesday", "friday"]
days = array.each_with_object(Hash.new(0)) do |e, total|
total[e] += 1
end
会给你这个:
{"wednesday"=>3, "thursday"=>1, "friday"=>2}
A' one-line'解决你的问题:
days = Invitation.pluck(:created_at).each_with_object(Hash.new(0)) do |e, total|
total[e.strftime("%A")] += 1
end
答案 2 :(得分:3)
如果您使用的是postgresql,您可以在数据库级别进行查询,只需使用Ruby来映射结果:
Invitation
.select("EXTRACT(DOW FROM created_at) AS day_of_the_week, COUNT(*) AS total_records")
.group("day_of_the_week")
.map {|result| [Date::DAYNAMES[result.day_of_the_week], result.total_records] }
.to_h
#=> {"Friday"=>4, "Tuesday"=>2, "Thursday"=>5, "Monday"=>3, "Wednesday"=>5, "Saturday"=>3}
通过这种方式,您可以避免加载所有的Invitation对象,只需执行一次查询。
答案 3 :(得分:0)
如果它是红宝石Array
,并且希望按值分组
invites = ["wednesday", "thursday", "friday", "wednesday", "wednesday", "friday"]
invite_group = Hash.new(0)
invites.each { |invite| invite_group[invite] += 1 }
# invite_group => {"wednesday"=>3, "thursday"=>1, "friday"=>2}
或使用key?
方法
invite_group = Hash.new
# invite_group = {}
invites.each { |invite| if invite_group.key?(invite); invite_group[invite] += 1; else invite_group[invite] = 1; end}
# # invite_group => {"wednesday"=>3, "thursday"=>1, "friday"=>2}