我有一个日期范围,我用它来查询数据库。返回的结果是一个类似哈希的数组:
[
{: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-13
到2014-04-18
。
输出最终只是数据分组月份的基本数组并加总。所以上面的例子应该产生:
[0, 1, 0, 6, 11, 2]
这些数组项目协调为:11月,12月,1月,2月,3月,4月。
FWIW,我正在运行Ruby 2.0.0,这是Rails 4应用程序的一部分,如果碰巧有一些特殊的Rails辅助方法在这里很有用。
答案 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]
rails您可以使用#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 }