完整的哈希键,空日期

时间:2017-08-07 20:34:18

标签: ruby

我有一个以周为关键字的哈希:

{"16 2016"=>6.0, "31 2016"=>7.5, "04 2017"=>8.666666666666666, "14 2017"=>7.5, "15 2017"=>8.4, "17 2017"=>7.333333333333333, "20 2017"=>7.571428571428571, "25 2017"=>6.75, "29 2017"=>6.8, "30 2017"=>6.7272727272727275}

我想显示一个图表行,但是我的哈希值中的空白月份。我知道如何获得空周并给出具有值的前一个值。

{"16 2016"=>6.0, "17 2016"=>6.0, "31"=>7.5}

我跟着this solution用我的月份哈希来做。

当我更改strptime以解析"%W, %Y"时,视图永远不会停止加载。

3 个答案:

答案 0 :(得分:1)

自从你问了几个月以来,这是一个灵活的方法。您可能希望将其放入类中并将方法拆分为多个部分。另外你可能想要添加:年份选项,如果我帮你了:

require 'date'

def fill_gaps(input, step)
  format = case step
  when :month then '%b %Y'
  when :week then '%W %Y'
  end
  current, *rest, stop = input.keys.map do |string|
    Date.strptime(string, format)
  end.sort

  {}.tap do |output|
    previous_value = nil
    while current <= stop
      key = current.strftime(format)
      output[key] = input.fetch(key, previous_value)

      current = case step
      when :month then current >> 1
      when :week then current + 7
      end
      previous_value = output[key]
    end

  end
end

h = {"Apr 2016"=>6.0, "Aug 2016"=>7.5, "Jan 2017"=>8.666666666666666, "Apr 2017"=>7.333333333333333, "May 2017"=>7.571428571428571, "Jun 2017"=>6.75, "Jul 2017"=>6.7272727272727275}
p h
p fill_gaps(h, :month)

h = {"16 2016"=>6.0, "31 2016"=>7.5, "04 2017"=>8.666666666666666, "14 2017"=>7.5, "15 2017"=>8.4, "17 2017"=>7.333333333333333, "20 2017"=>7.571428571428571, "25 2017"=>6.75, "29 2017"=>6.8, "30 2017"=>6.7272727272727275}
p h
p fill_gaps(h, :week)

答案 1 :(得分:1)

以下是用前一周值填写所有缺失周数的另一种方法:

def all_weeks(input)
  dates = input.keys.map { |d| Date.commercial(*d.split.map(&:to_i).reverse) }
  range = (dates.min..dates.max).to_a.map { |d| d.strftime("%W %Y") }.uniq

  current_value = 0

  range.each_with_object({}) do |date, result|
    result[date] = current_value = input[date] || current_value
  end
end

请注意使用Date,但由于您使用的是rails,因此无需require

使用它:

weeks = {"16 2016"=>6.0, "31 2016"=>7.5, "04 2017"=>8.666666666666666, "14 2017"=>7.5, "15 2017"=>8.4, "17 2017"=>7.333333333333333, "20 2017"=>7.571428571428571, "25 2017"=>6.75, "29 2017"=>6.8, "30 2017"=>6.7272727272727275}
all_weeks(weeks)

答案 2 :(得分:1)

require 'date'

def fill_in(h)
  fwy, lwy = h.keys.minmax_by { |str| str.split.map(&:to_i).reverse }
  last_val = nil 
  (week_yr_str_to_date(fwy)..week_yr_str_to_date(lwy)).step(7).
    each_with_object({}) do |d,g| 
      wystr = date_to_week_yr_str(d)
      g[wystr] = h.fetch(wystr, last_val)
      last_val = g[wystr]
  end
end

def week_yr_str_to_date(wystr)
  Date.strptime(wystr, '%U %Y')
end

def date_to_week_yr_str(d)
  "#{1+((d-date_1st_Sunday(d.year)).to_i)/7} #{d.year}"
end

def date_1st_Sunday(y)
  start_date = Date.new(y)
  start_date += (7 - start_date.wday)%7
end

h = { "49 2016"=>649, "51 2016"=>651, "2 2017"=>701, "4 2017"=>703 }

fill_in(h)
  #=> {"49 2016"=>649, "50 2016"=>649, "51 2016"=>651, "52 2016"=>651,
  #    "1 2017"=>651, "2 2017"=>701, "3 2017"=>701, "4 2017"=>703}