创建匹配键和增量值的哈希值

时间:2017-06-28 00:26:53

标签: ruby-on-rails ruby

我有一个巨大的数组,列出了创建对象的星期几,所以我最终得到了一个类似于以下内容的数组:

["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

4 个答案:

答案 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}