我有一个哈希数组,每个哈希都有date
个键,如下所示:
data = [
{date: Date.new(2012,1), name: "1"},
{date: Date.new(2012,8), name: "2"},
{date: Date.new(2013,2), name: "3"},
{date: Date.new(2013,6), name: "4"},
{date: Date.new(2013,9), name: "5"},
{date: Date.new(2014,3), name: "6"},
{date: Date.new(2014,4), name: "7"},
{date: Date.new(2014,8), name: "8"},
]
我想按业务年度对哈希进行分组,换句话说就是4月到明年3月这样:
[
[{date: Date.new(2012,1), name: "1"}],
[{date: Date.new(2012,8), name: "2"},
{date: Date.new(2013,2), name: "3"}],
[{date: Date.new(2013,6), name: "4"},
{date: Date.new(2013,9), name: "5"},
{date: Date.new(2014,3), name: "6"}],
[{date: Date.new(2014,4), name: "7"},
{date: Date.new(2014,8), name: "8"}]
]
要完成我这样写的:
result = []
4.times do |i|
result[i] = []
data.each do |datum|
result[i] << datum if datum[:date].between?(Date.new(2011+i,4), Date.new(2012+i,3))
end
end
但是这段代码只有在我知道我处理的时间范围时才有效。 我觉得有更好的方法可以更简洁地在Ruby中编写它。
我该如何写这个函数?
答案 0 :(得分:3)
您可以使用Enumerable#group_by:
require 'date'
data.group_by { |h| (h[:date].month > 3) ? h[:date].year : h[:date].year - 1 }
#=> {2011=>[{:date=>#<Date: 2012-01-01 ((2455928j,0s,0n),+0s,2299161j)>, :name=>"1"}],
# 2012=>[{:date=>#<Date: 2012-08-01 ((2456141j,0s,0n),+0s,2299161j)>, :name=>"2"},
# {:date=>#<Date: 2013-02-01 ((2456325j,0s,0n),+0s,2299161j)>, :name=>"3"}],
# 2013=>[{:date=>#<Date: 2013-06-01 ((2456445j,0s,0n),+0s,2299161j)>, :name=>"4"},
# {:date=>#<Date: 2013-09-01 ((2456537j,0s,0n),+0s,2299161j)>, :name=>"5"},
# {:date=>#<Date: 2014-03-01 ((2456718j,0s,0n),+0s,2299161j)>, :name=>"6"}],
# 2014=>[{:date=>#<Date: 2014-04-01 ((2456749j,0s,0n),+0s,2299161j)>, :name=>"7"},
# {:date=>#<Date: 2014-08-01 ((2456871j,0s,0n),+0s,2299161j)>, :name=>"8"}]}