按日期对哈希数组进行分组和求和

4

我有一个哈希数组,像这样:

[{:created=>Fri, 22 Jan 2014 13:02:13 UTC +00:00, :amount=>20}, 
{:created=>Fri, 27 Jan 2014 13:14:57 UTC +00:00, :amount=>15}, 
{:created=>Fri, 27 Jan 2014 14:42:40 UTC +00:00, :amount=>10}, 
{:created=>Fri, 28 Jan 2014 15:26:58 UTC +00:00, :amount=>10}, 
{:created=>Fri, 28 Jan 2014 15:30:18 UTC +00:00, :amount=>20}, 
{:created=>Fri, 31 Jan 2014 15:32:46 UTC +00:00, :amount=>50}, 
{:created=>Fri, 31 Jan 2014 15:33:29 UTC +00:00, :amount=>40}]

我希望能按日期对这些哈希值进行分组,并求和金额。因此,在我的示例中,输出将是:
[{:created=>"2014-01-22", :amount=>20}, 
{:created=>"2014-01-27", :amount=>25}, 
{:created=>"2014-01-28", :amount=>30}, 
{:created=>"2014-01-31", :amount=>90}]
1个回答

9
我会按照以下步骤进行操作:
require 'date'

a = [{:created=> 'Fri, 22 Jan 2014 13:02:13 UTC +00:00', :amount=>20}, 
{:created=>'Fri, 27 Jan 2014 13:14:57 UTC +00:00', :amount=>15}, 
{:created=>'Fri, 27 Jan 2014 14:42:40 UTC +00:00', :amount=>10}, 
{:created=>'Fri, 28 Jan 2014 15:26:58 UTC +00:00', :amount=>10}, 
{:created=>'Fri, 28 Jan 2014 15:30:18 UTC +00:00', :amount=>20}, 
{:created=>'Fri, 31 Jan 2014 15:32:46 UTC +00:00', :amount=>50}, 
{:created=>'Fri, 31 Jan 2014 15:33:29 UTC +00:00', :amount=>40}]

hsh = a.group_by { |h| Date.parse h[:created] }.map do |k,v| 
  {:created => k.to_s,:amount => v.map {|h1| h1[:amount]}.inject(:+)} 
end
hsh
# => [{:created=>"2014-01-22", :amount=>20},
#     {:created=>"2014-01-27", :amount=>25},
#     {:created=>"2014-01-28", :amount=>30},
#     {:created=>"2014-01-31", :amount=>90}]

我认为Arup明智地将字符串解析为日期,但是...group_by { |h| h[:created].first(16) }...也可以(或者您可以使用正则表达式)。使用Date.parse的一个优点是,如果它发现日期字符串不合法,它会引发异常。 - Cary Swoveland
除了OP的日期值不是字符串;它们是“Date”对象(否则它们将被引用)。 - Matt
@Matt 没什么大不了的... 在这种情况下,我会使用 h[:created].to_s 而不是 Date.parse h[:created] .. 而且,我会写成 :created => k.. 而不是 :created => k.to_s..。但我的意思就是这样。 - Arup Rakshit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接