根据业务年份的“:date”值对哈希数组进行分组
Group a array of hash according to their `:date` value by business year
我有一个散列数组,每个散列中有 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"},
]
我想按营业年度对哈希进行分组,换句话说,四月到明年三月,如下所示:
[
[{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更简洁
这个函数怎么写?
你可以使用 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"}]}
我有一个散列数组,每个散列中有 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"},
]
我想按营业年度对哈希进行分组,换句话说,四月到明年三月,如下所示:
[
[{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更简洁
这个函数怎么写?
你可以使用 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"}]}