2017-08-07 107 views
-1

我有一個星期的哈希作爲關鍵字:完整的哈希鍵

{"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

這裏的另一種方式來填補與前一週值的所有失蹤周:

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,但由於您使用導軌,因此無需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) 
+1

只需注意,它將每個月的第一週標識爲「0」周,而不是「1周」(這很好)。 –

+1

我沒有意識到'%U'和'%W' Date#strptime'指令,直到我看到您的答案,所以用前者來簡化我的答案的一部分。我也不知道「日期::商業」。所有好東西。 –

+0

@CarySwoveland直到我在製作這個答案時瀏覽文檔時,我才意識到「Date :: commercial」。在Ruby中跟蹤每個方法似乎是不可能的。 – Gerry

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}