我有一个日期和数量的哈希值如下:
{
"2014-01-30"=>200.1,
"2014-02-01"=>27.86,
"2014-02-02"=>55.72,
"2014-02-03"=>83.58,
"2014-02-04"=>83.58,
"2014-02-05"=>76.41,
"2014-02-06"=>187.85,
"2014-02-07"=>27.86,
"2014-02-08"=>27.86,
"2014-02-09"=>55.72,
"2014-02-10"=>269.34,
"2014-02-11"=>83.58,
"2014-02-12"=>159.99,
"2014-02-13"=>373.61,
"2014-02-14"=>264.26,
"2014-02-15"=>236.4,
"2014-02-17"=>215.71,
"2014-02-18"=>55.72,
"2014-02-19"=>132.13,
"2014-02-20"=>104.27,
"2014-02-21"=>83.58,
"2014-02-22"=>104.27,
"2014-02-23"=>159.99,
"2014-02-24"=>27.86,
"2014-02-25"=>172.24,
"2014-02-27"=>380.78,
"2014-02-28"=>336.82,
"2014-03-01"=>55.72,
"2014-03-02"=>83.58,
"2014-03-03"=>83.58,
"2014-03-04"=>224.02,
"2014-03-05"=>574.76,
"2014-03-06"=>853.14,
"2014-03-07"=>27.86,
"2014-03-09"=>83.58,
"2014-03-10"=>241.48,
"2014-03-11"=>208.54,
"2014-03-12"=>368.53,
"2014-03-13"=>941.42,
"2014-03-14"=>396.39,
"2014-03-15"=>320.71,
"2014-03-16"=>144.38,
"2014-03-17"=>215.71,
"2014-03-18"=>83.58,
"2014-03-19"=>227.44,
"2014-03-20"=>104.27,
"2014-03-21"=>111.32,
"2014-03-22"=>104.27,
"2014-03-23"=>238.86,
"2014-03-25"=>172.24
}
我想要做的是将这些日期映射到"周"和"月"小组并将金额加起来。
因此,基本上取出开始日期和结束日期(在本例中为2014-01-30
和2014-03-25
),然后将其划分为日历周期和月期,并将所有天数总和那范围。
在上面的示例数据中,您会将其分为实际周数。请注意,其中一些分组只有6个项目,因为其中一天没有金额。
对于输出,我想要一个每周/每月范围总和数量的数组。
上述示例数据的输出为:[283.68, 542.86, 1387.18, 855.67, 1057.00, 1846.94, 2621.45, 1085.45, 172.24]
FWIW,我正在起诉Ruby 2和Rails 4。
答案 0 :(得分:3)
# This for using outside Rails, remove if on Rails
require 'date'
gem 'activesupport'
require 'active_support/core_ext/date'
require 'active_support/core_ext/enumerable'
hash = {
"2014-01-30"=>200.1,
"2014-02-01"=>27.86,
"2014-02-02"=>55.72,
[...]
"2014-03-25"=>172.24
}
# group by week
p Hash[ hash.map { |h, v| [Date.parse(h), v] } ]
.group_by { |h, v| h.cweek }
.values
.map { |v| v.sum { |v| v.last } }
.map { |v| v.round(2) }
#=> [283.68, 542.86, 1387.18, 855.67, 1057.0, 1846.94, 2621.45, 1085.45, 172.24]
# group by month
p Hash[ hash.map { |h, v| [Date.parse(h), v] } ]
.group_by { |h, v| h.month }
.values
.map { |v| v.sum { |v| v.last } }
.map { |v| v.round(2) }
#=> [200.1, 3786.99, 5865.38]
经过一些重构:
# group by week
p hash
.group_by { |h, _| Date.parse(h).cweek }
.map { |_, v| v.sum { |v| v.last }.round(2) }
# group by month
p hash
.group_by { |h, _| Date.parse(h).month }
.map { |_, v| v.sum { |v| v.last }.round(2) }
如果您对我使用下划线的原因感到好奇:http://po-ru.com/diary/rubys-magic-underscore/
答案 1 :(得分:0)
试试:
start_date = hash.min[0]
end_date = hash.max[0]
result = []
(start_date..end_date).each do |date|
if date.wday == start_date.wday
result << hash[date]
else
result[-1] += hash[date]
end
end
或只是为了好玩:
(h.min[0]..h.max[0]).each {|d| (d.wday == h.min[0].wday && r << h[d])||(r[-1]+=h[d])}