2014-04-18 48 views
0

我有一個日期範圍,我正用它來查詢數據庫。返回的結果是哈希的數組,像這樣:按月分組和總計哈希,包括當沒有數據時

[ 
    {: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

可以使用#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 } 
+0

除非我錯過了一些東西......這不是我一直在尋找的東西。如前所述,數據需要彙總,需要考慮遺漏的月份。 – Shpigford

+0

@Shpigford更新 –

+0

謝謝。你介意解釋它是如何工作的嗎? – Shpigford