2013-04-11 72 views
0

我试图计算每个月数据库中的记录数。但是,有个月没有任何记录,我想补充的到我的阵列以及当按月分组时,向阵列添加空月份

@activity = Activity.find(params[:id]) 
records_by_month = @activity.records.max_12_months.group_by{ |t| t.happened.beginning_of_month } 
hori = Array.new 
verti = Array.new 
records_by_month.sort.each do |month, recs| 
    hori.push(month.strftime('%B')) 
    verti.push(recs.count) 
end 

这records_by_month的样子:

#<OrderedHash {Tue, 01 Jan 2013=>[#<Record id: 37, details: "", 
happened: "2013-01-09", duration: nil, activity_id: 21, created_at: "2013-04-11 14:31:30", 
updated_at: "2013-04-11 14:31:30", price: 15.0>], Fri, 01 Mar 2013=> 
[#<Record id: 36, details: "", happened: "2013-03-04", duration: nil, 
activity_id: 21, created_at: "2013-04-11 14:31:12", updated_at: "2013-04-11 14:31:12", price: 15.0>], 
Thu, 01 Nov 2012=>[#<Record id: 38, details: "", happened: "2012-11-29", 
duration: nil, activity_id: 21, created_at: "2013-04-11 14:31:51", 
updated_at: "2013-04-11 14:31:51", price: 15.0>]}> 

任何想法如何,我可以将月份名称添加到hori,并将0添加到没有记录的每个月份的verti?

+0

你可以给'records_by_month'线的输出? – 2013-04-11 19:41:28

+0

我更新了我的文章 – networkprofile 2013-04-11 20:05:12

+0

为什么要添加'0'?需要这些信息。 – 2013-04-11 20:25:32

回答

1

好的(稍做改动以便测试)......这样的事情呢?

ALL = [%w{ 
    January February March 
    April May  June 
    July August September 
    October November December 
}, [0] * 12].transpose 
hori = Hash[ALL] 
verti = Hash[ALL] 
{'January' => 1, 'March' => 5}.each do |month, recs| 
    hori[month] = :test 
    verti[month] = recs 
end 
p hori.sort.map(&:last) # => [0, 0, 0, 0, :test, 0, 0, :test, 0, 0, 0, 0] 
p verti.sort.map(&:last) # => [0, 0, 0, 0, 1, 0, 0, 5, 0, 0, 0, 0] 
+0

请问您可以添加一些意见到底发生了什么?我猜我应该用'records_by_month'替换'{'January'=> 1,'March'=> 5}',但我不太了解代码。 – networkprofile 2013-04-11 20:07:49

+0

你是对的。这个想法是,以每个月为一个关键点很容易。 '[0] * 12'和'.transpose'只是在每个月后添加一个任意类型的值(在这种情况下为0),这与写作完全相同:'{'January'=> 0,'February'= > 0,...}'。由于我们构造的是Hash对象而不是数组,因此我们不需要对'records_by_month'进行排序,并且在可用键的值被设置后(对于'horti'和'verti'),只需要通过映射每个键散列(实际上,它们是数组之后)通过Symbol的#to_proc实例方法通过'element.last'实现。 (:last) – DigitalRoss 2013-04-11 20:56:37

+0

所以,是的,你需要用'records_by_month'替换'{...}',你可能还必须从block参数'month'中提取真实的月份字符串,并且稍微改变赋值。 – DigitalRoss 2013-04-11 21:00:37

0

这是你的问题的一个提示,而不是完整的解决方案:

require 'date' 

h = {"Tue, 01 Jan 2013" =>[Record_id: 37, details: "", 
happened: "2013-01-09", duration: nil, activity_id: 21, created_at: "2013-04-11 14:31:30", 
updated_at: "2013-04-11 14:31:30", price: 15.0], "Fri, 01 Mar 2013" => 
[Record_id: 36, details: "", happened: "2013-03-04", duration: nil, 
activity_id: 21, created_at: "2013-04-11 14:31:12", updated_at: "2013-04-11 14:31:12", price: 15.0], 
"Thu, 01 Nov 2012" =>[Record_id: 38, details: "", happened: "2012-11-29", 
duration: nil, activity_id: 21, created_at: "2013-04-11 14:31:51", 
updated_at: "2013-04-11 14:31:51", price: 15.0]} 

hori = {} 
verti = {} 

h.each {|k,v| hori[Date.parse(k).strftime('%B')] = v} 
p hori 

Date::MONTHNAMES.compact.map {|m| verti[m]=0 unless hori.keys.include? m} 
p verti 

输出:

{"January"=>[{:Record_id=>37, :details=>"", :happened=>"2013-01-09", :duration=>nil, :activity_id=>21, :created_at=>"2013-04-11 14:31:30", :updated_at=>"2013-04-11 14:31:30", :price=>15.0}], "March"=>[{:Record_id=>36, :details=>"", :happened=>"2013-03-04", :duration=>nil, :activity_id=>21, :created_at=>"2013-04-11 14:31:12", :updated_at=>"2013-04-11 14:31:12", :price=>15.0}], "November"=>[{:Record_id=>38, :details=>"", :happened=>"2012-11-29", :duration=>nil, :activity_id=>21, :created_at=>"2013-04-11 14:31:51", :updated_at=>"2013-04-11 14:31:51", :price=>15.0}]} 

{"February"=>0, "April"=>0, "May"=>0, "June"=>0, "July"=>0, "August"=>0, "September"=>0, "October"=>0, "December"=>0}