集团&按月汇总哈希,包括没有数据时

时间:2014-04-18 16:29:49

标签: ruby-on-rails ruby

我有一个日期范围,我用它来查询数据库。返回的结果是一个类似哈希的数组:

[
  {:created=>"2013-12-10", :amount=>1}, 
  {:created=>"2014-02-20", :amount=>1}, 
  {:created=>"2014-02-23", :amount=>4}, 
  {:created=>"2014-02-24", :amount=>1}, 
  {:created=>"2014-03-06", :amount=>1}, 
  {:created=>"2014-03-14", :amount=>3}, 
  {:created=>"2014-03-15", :amount=>1}, 
  {:created=>"2014-03-17", :amount=>1}, 
  {:created=>"2014-03-20", :amount=>1}, 
  {:created=>"2014-03-21", :amount=>1}, 
  {:created=>"2014-03-24", :amount=>1}, 
  {:created=>"2014-03-25", :amount=>1}, 
  {:created=>"2014-03-28", :amount=>1}, 
  {:created=>"2014-04-05", :amount=>1}, 
  {:created=>"2014-04-07", :amount=>1}
] 

我需要做的是按月对amount进行分组和求和,如果一个月没有数据但属于初始范围的一部分,请显示0

因此,在上面的示例中,我查询数据库的日期范围是2013-11-132014-04-18

输出最终只是数据分组月份的基本数组并加总。所以上面的例子应该产生:

[0, 1, 0, 6, 11, 2]

这些数组项目协调为:11月,12月,1月,2月,3月,4月。

FWIW,我正在运行Ruby 2.0.0,这是Rails 4应用程序的一部分,如果碰巧有一些特殊的Rails辅助方法在这里很有用。

1 个答案:

答案 0 :(得分:1)

您可以使用#group_by方法按年份和月份进行分组,然后使用#map#uniq#reduce的组合进行分组,以获得正确的Array

# grouping record by year and month, and then sorting them
g = a.group_by {|v| Date.parse(v[:created][0,7] + '-01') }.sort

# generating a result hash
h = Hash[g]

# generating range
range = Date.new(2013,11)..Date.new(2014,04)

# here we firstly remap to get *year-month* list by dates, which will contain only
# one date per month, then we calculate sum for each month value.
range.to_a.map {|d| Date.new(d.year,d.month,1)}.uniq.map {|d| h[d] && h[d].reduce(0) {|sum,h| sum + h[:amount]} || 0 }

# => [0, 1, 0, 6, 11, 2] 

您可以使用#try方法:

range.to_a.map {|d| Date.new(d.year,d.month,1)}.uniq.map {|d| h[d].try(:reduce, 0) {|sum,h| sum + h[:amount]} || 0 }