按月和周分组

时间:2017-07-26 20:36:54

标签: ruby-on-rails ruby hash charts

我想知道将哈希分组的最佳方法是什么 一个月和一周{date->value}

{Sat, 23 Apr 2016=>6.0, Mon, 06 Mar 2017=>9.0, Tue, 04 Apr 2017=>13.0, Tue, 11 Apr 2017=>25.0}

我想得到一个结果:

{Apr 2016=>6, Mar 2017=>9, Apr 2017=>38}

我尝试使用Groupdate / Chartkick但是我没有得到好结果。

由于

2 个答案:

答案 0 :(得分:1)

鉴于OP示例的预期结果,我假设OP表示“月和年”而不是“周和月”。

我还假设输入散列的键是字符串(而不是日期对象),返回的散列的键是字符串。无论如何,我会使用Hash::new,默认值为零(计算哈希)。有关详细信息,请参阅文档。

dates = {"Sat, 23 Apr 2016"=>6.0, "Mon, 06 Mar 2017"=>9.0,
         "Tue, 04 Apr 2017"=>13.0, "Tue, 11 Apr 2017"=>25.0}

dates.each_with_object(Hash.new(0)) { |(k,v),h| h[k[-8..-1]] += v.to_i }
   #=> {"Apr 2016"=>6, "Mar 2017"=>9, "Apr 2017"=>38}

如果输入哈希的日期是日期对象,我们可以执行以下操作。首先创建日期对象。

require 'date'

dates =  {"Sat, 23 Apr 2016"=>6.0, "Mon, 06 Mar 2017"=>9.0,
         "Tue, 04 Apr 2017"=>13.0, "Tue, 11 Apr 2017"=>25.0}.
  map { |str, v| [Date.parse(str), v] }.to_h
    #=> {#<Date: 2016-04-23 ((2457502j,0s,0n),+0s,2299161j)>=>6.0,
    #    #<Date: 2017-03-06 ((2457819j,0s,0n),+0s,2299161j)>=>9.0,
    #    #<Date: 2017-04-04 ((2457848j,0s,0n),+0s,2299161j)>=>13.0,
    #    #<Date: 2017-04-11 ((2457855j,0s,0n),+0s,2299161j)>=>25.0}

然后我们可以写

dates.each_with_object(Hash.new(0)) { |(k,v),h| h[k.strftime("%b %Y")] += v.to_i }
  #=> {"Apr 2016"=>6, "Mar 2017"=>9, "Apr 2017"=>38}

请参阅DateTime#strftime

这是一个纯Ruby解决方案。

答案 1 :(得分:0)

如果您有数据哈希(作为哈希),则可以使用reduce

这个月将是

data.reduce({}) do |memo, (date, value)|
  new_date = date.beginning_of_month.strftime("%B %Y")
  memo[new_date] ||= 0
  memo[new_date] += value
  memo
end

这一周将是

data.reduce({}) do |memo, (date, value)|
  new_date = date.beginning_of_week.strftime("%B %e %Y")
  memo[new_date] ||= 0
  memo[new_date] += value
  memo
end

您可以使用this document根据需要修改strftime格式。