我有一个以周为关键字的哈希:
{"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"
时,视图永远不会停止加载。
答案 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}