我有一个哈希
{"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}
我希望显示一个图表行,但我的哈希中的空白月会创建丑陋的图表, 我会知道如何获得空的月份,并给予以前的值有价值来获得类似
的东西{"Apr 2016"=>6.0, "May 2016"=>6, "June 2016"=>6, "July 2016"=>6 "Aug 2016"=>7.5, "Jan 2017"=>8.666666666666666...}
更新:我得到所有的值,但我不知道当值为空时如何分配前一个值,我尝试了很多东西,但没有任何工作
答案 0 :(得分:1)
<强>代码强>
require 'date'
def fill_in(h)
month, date_last = h.keys.map { |s| Date.strptime(s, '%b %Y') }.minmax
h_out = {}
last = nil
loop do
str = month.strftime('%b %Y')
h_out[str] = h.fetch(str, last)
last = h_out[str]
return h_out if month == date_last
month = month >> 1
end
end
示例强>
h = { "May 2016"=>6.0, "Aug 2016"=>7.5, "Jan 2017"=>8.6, "Nov 2016"=>7.3 }
fill_in(h)
#=> {"May 2016"=>6.0, "Jun 2016"=>6.0, "Jul 2016"=>6.0,
# "Aug 2016"=>7.5, "Sep 2016"=>7.5, "Oct 2016"=>7.5,
# "Nov 2016"=>7.3, "Dec 2016"=>7.3, "Jan 2017"=>8.6}
<强>解释强>
请参阅Date::strptime,Date#strftime,Date#>>,Enumerable#minmax和Hash#fetch。
我们来看看示例中给出的h
的步骤。
month, date_last = h.keys.map { |s| Date.strptime(s, '%b %Y') }.minmax
#=> [#<Date: 2016-05-01 ((2457510j,0s,0n),+0s,2299161j)>,
# #<Date: 2017-01-01 ((2457755j,0s,0n),+0s,2299161j)>]
month
#=> #<Date: 2016-05-01 ((2457510j,0s,0n),+0s,2299161j)>
date_last
#=> #<Date: 2017-01-01 ((2457755j,0s,0n),+0s,2299161j)>
h_out = {}
last = nil
执行一次循环计算
str = month.strftime('%b %Y')
#=> #<Date: 2016-05-01 ((2457510j,0s,0n),+0s,2299161j)>.strftime('%b %Y')
#=> "May 2016"
h_out[str] = h.fetch("May 2016", nil)
#=> h.fetch(str, last)
#=> 6.0
last = h_out[str]
#=> 6.0
return h_out if month == date_last
# <do not return>
month = month >> 1
#=> #<Date: 2016-06-01 ((2457541j,0s,0n),+0s,2299161j)>
现在再次进行循环。
str = month.strftime('%b %Y')
#=> "Jun 2016"
h_out[str] = h.fetch(str, last)
#=> 6.0
此时fetch
使用默认值last #=> 6.0
),因为h
没有键"Jun 2016"
。
last = h_out[str]
#=> 6.0
return h_out if month == date_last
# <do not return>
month = month >> 1
#=> #<Date: 2016-07-01 ((2457571j,0s,0n),+0s,2299161j)>
其余的计算方法类似。
答案 1 :(得分:0)
请阅读更新。
您需要填补空白:
require 'date'
data = {'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}
range = Date.parse('1.4.2016')..Date.parse('1.7.2017')
range.each do |date|
key = date.strftime('%b %Y')
data[key] ||= 0
end
这会创建一个包含开始日期和结束日期的日期范围,然后对其进行迭代。它从日期(strftime
)创建一个String,并检查它是否已经在哈希值(||=
)中,如果没有,则将值设置为0
根据您呈现图表的方式以及实际显示的内容,0
可能是错误的值,您可能需要将其设置为nil
。
更新: 我刚刚意识到这不是最有效的方法,因为范围将包含每天的条目,而不是每月。我将代码保留在答案中,但您应该使用类似的内容:
require 'date'
data = {'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}
current = Date.parse('1.4.2016')
stop = Date.parse('1.7.2017')
while current <= stop do
key = current.strftime('%b %Y')
data[key] ||= 0
current = current >> 1
end