2014-04-18 2 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-13에서 2014-04-18까지입니다.

출력은 궁극적으로 그룹화 된 데이터의 기본 배열이며 합계입니다. 따라서 위의 예는 생산한다 : 11 월, 12 월, 1 월, 2 월, 3 월, 4 월 : 그 배열 항목이 좌표

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

.

FWIW, Ruby 2.0.0을 실행 중입니다. 여기에 유용한 Rails 헬퍼 메소드가 있으면 Rails 4 앱의 일부입니다.

답변

1

Array 당신은 적절한 얻을 #group_by년에 의해 그룹 방법 및 월, #map, #uniq#reduce의 다음 조합을 사용할 수 있습니다 :

: 에 대한

# 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