Ruby on rails 保存最近几个月的哈希

Ruby on rails 保存最近几个月的哈希,ruby-on-rails,arrays,ruby,hash,Ruby On Rails,Arrays,Ruby,Hash,我有一个哈希数组。像这样的 transactions = [{"date"=>"2014-07-21", "amount"=>200}, {"date"=>"2012-06-21", "amount"=>400}, {"date"=>"2014-08-21", "amount"=>100}, {"date"=>"2014-08-12", "amount"=>1

我有一个哈希数组。像这样的

transactions = [{"date"=>"2014-07-21", "amount"=>200},
               {"date"=>"2012-06-21", "amount"=>400},
               {"date"=>"2014-08-21", "amount"=>100},
               {"date"=>"2014-08-12", "amount"=>150},
               {"date"=>"2014-06-15", "amount"=>230}
               {"date"=>"2013-05-21", "amount"=>900},]
我希望能够保存每个月的总金额,然后显示最近3个月到今天的日期及其总金额。像这样的

transactions = [{"date"=>"2014-07-21", "amount"=>200},
               {"date"=>"2012-06-21", "amount"=>400},
               {"date"=>"2014-08-21", "amount"=>100},
               {"date"=>"2014-08-12", "amount"=>150},
               {"date"=>"2014-06-15", "amount"=>230}
               {"date"=>"2013-05-21", "amount"=>900},]
总计:06-14 230美元 07-14 $200 08-14 250美元

我有这个方法,但我不知道如何得到只有最后3个月,把我的数据库字段,以及如何打印出来

def income_by_month
    @payroll_transactions = current_user.transactions
    @recent_payroll = @payroll_transactions.find_all {90.days.ago.to_date..Date.today}.map #finds transactions within 90 days
     @amount_by_month = @recent_payroll.group_by { |t| t.date.to_date.month }.map do |month, transactions|
        [month, transactions.sum(:amount)] #Groups transactions by month and adds month total
      end.to_h
-编辑-

我想出了一个方法,只获取过去30天的事务,我更新了我的方法来显示它。现在我的问题是如何保存答案(是否将其保存在一个字段中作为数组?),然后如何在视图中显示答案。就像我在这里展示的一样。如何按顺序逐行打印每个键和值

Totals:   06-14    $230
          07-14    $200
          08-14    $250
-编辑-
对不起,我的数据库是mongoid数据库。我想保存最近3个月到今天的日期,不管是否有可用金额。

让我从您的代码片段的快速注释开始:

group_by { |t| t.date.to_date.month }
请注意,按单个
月对对象进行分组并不需要一年的时间,因此它将在一个容器中汇总2012年和2014年的交易金额。因此,您真正想要的是基于月份和年份值进行分组

考虑到通过输入数组减少冗余迭代的数量(并使用不必要的聚合),我提出了以下建议:

last_months = transactions.map{|i| Date.parse(i["date"]).strftime("%m-%Y")}.uniq.sort.last(3)
result      = last_months.inject({}){|result, input| result[input] = 0; result}
transactions.inject(result) do |result, object|
  # NOTE: we're already doing dates parsing and strftime two times here.
  # In case you operate on Date objects themselves in your code, this is not the case.
  # But the real perfomance measurement between summing all values up
  # and strftiming more than once should be done additionally.
  month = Date.parse(object["date"]).strftime("%m-%Y")
  result[month] += object["amount"] if result[month]
  result
end
# result now equals to {"06-2014"=>230, "07-2014"=>200, "08-2014"=>250}
首先,我们得到最后三个月(和几年)。 接下来,我们创建一个散列来包含仅包含最后几个月键的聚合值。最后,我们仅对后3个月的交易进行了金额汇总

因此,只要ruby哈希(ruby v.1.9+)保持键的顺序,您就可以简单地迭代它们以打印出:

result.each{|k,v| puts "#{k}: #{v}"}
# 06-2014: 230
# 07-2014: 200
# 08-2014: 250

这里要注意的最后一件事是,在服务器代码内部进行这种聚合不是很有效。更诱人的选择是将此计算移到数据库层。

ActiveSupport有一些非常灵活的日期方法,如date#start(月初):

需要“日期”
需要“主动支持/核心扩展”
def流程交易组(月、交易)
{
月份:月份strftime(“%Y/%m”),
总计:transactions.map{| t | t[“金额”]}.reduce(:+)
}
结束
def过程_事务(事务)
交易
.group_by{t|Date.parse(t[“Date”])。月初}
。选择{月,{trxs}月<3.months.ago}
.map{month,trxs | process|u transaction_group(month,trxs)}
结束
###############
交易记录=[{“日期”=>“2014-07-21”,“金额”=>200},
{“日期”=>“2012-06-21”,“金额”=>400},
{“日期”=>“2014-08-21”,“金额”=>100},
{“日期”=>“2014-08-12”,“金额”=>150},
{“日期”=>“2014-06-15”,“金额”=>230},
{“日期”=>“2013-05-21”,“金额”=>900}]
处理交易(交易)
#=>[{:month=>“2014/07”、:total=>200}、{:month=>“2012/06”、:total=>400}、{:month=>“2014/08”、:total=>250}、{:month=>“2014/06”、:total=>230}、{:month=>“2013/05”、:total=>900}]

如果您只是想说明获取最后3个元素的方法,或者如何将数据推送到数据库,请您澄清一下?在后一种情况下,您应该更深入地了解数据库的设计以及如何存储这些数据。很抱歉,我的数据库是mongoid db。我想把最近三个月到今天的时间存起来,不管有没有钱。谢谢你的回答,我就要试试了。问题,这个聚合在我的模型中。您的意思是打印输出应该在模型级别还是整个信息聚合范围内?我只是想澄清一下。我的建议是编写
SQL
query来检索有关事务的所需信息(而不是像您现在所做的那样映射和注入哈希)。事务是我数据库中的哈希数组,因此我不确定是否可以调用SQL查询。我想调用日期范围内的所有事务,比如@transactions.find_all{t|date.parse(t[“date”])>=180.days.from_now.to_date}.map,但它一直告诉我日期范围不好