繁体   English   中英

如何跳过Ruby哈希中的空值

[英]How to skip over null values in Ruby hashes

我有一个数组,其中每个数组项都是带有日期值的哈希,如下面的示例所示。 实际上,它比较长,每个项目有大约20个日期而不是3个日期。我需要做的是获取每个项目的日期间隔值(即每个日期值之间有多少天)及其间隔的中位数。 我的代码如下:

require 'csv'
require 'date'

dateArray = [{:date_one => "May 1", :date_two =>"May 5", :date_three => " "}, {:date_one => "May 10", :date_two =>"May 10", :date_three => "May 20"}, {:date_one => "May 6", :date_two =>"May 11", :date_three => "May 12"}]

public
def median
sorted = self.sort
  len = sorted.length
  return (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
end

puts dateIntervals = dateArray.map{|h| (DateTime.parse(h[:date_two]) - DateTime.parse(h[:date_one])).to_i}
puts "\nMedian: " 
puts dateIntervals.median

返回以下日期间隔值和中间值:

4
0
5
Median: 4

但是,与第一项一样,这些项的某些值的:date_three值为空。 如果我尝试对:date_three:date_two values运行相同的方程式,如下所示,则将抛出错误,因为最后一个:date_three值为空。

没关系,我可以得到这个间隔,但是我仍然需要接下来的两个日期间隔(分别是10和1)。

尝试运行错误时,如何跳过返回错误的时间间隔?

我建议添加可以处理您期望的输入类型的辅助函数。 例如:

def date_diff(date_one, date_two)
    return nil if date_one.nil? || date_two.nil?
    (date_one - date_two).to_i
end

def str_to_date(input_string)
    DateTime.parse(input_string)
    rescue
    nil
end

dateArray.map{|h| date_diff(str_to_date(h[:date_three]), str_to_date(h[:date_two])) }
=> [nil, 10, 1]

dateArray.map{|h| date_diff(str_to_date(h[:date_three]), str_to_date(h[:date_two])) }.compact.median
=> 5.5

这样做的好处是,您可以随后为各个组件添加单元测试,以便轻松测试边缘情况(零日期,空字符串日期等)。

在地图块中,您只需添加一个检查以确保值不为空

dateIntervals = dateArray.map{ |h| 
  (DateTime.parse(h[:date_two]) - DateTime.parse(h[:date_one])).to_i unless any_blank?(h)
}

def any_blank?(h)
  h.each do |k, v|
    return true if v == " "
  end
end

首先,我将首先过滤掉空值(我检查字符串是否完全由空格组成或为空),然后使用现有代码比较其余值。 我添加了一个循环,该循环将序列中的所有值与下一个值进行比较。

dateArray = [
  { date_one: "May 1", date_two: "May 5", date_three: " ", date_four: "" },
  { date_one: "May 10", date_two: "May 10", date_three: "May 20" }
]

intervals = dateArray.map do |hash|
  filtered = hash.values.reject { |str| str =~ /^\s*$/ }
  (0...filtered.size-1).map { |idx| (DateTime.parse(filtered[idx+1]) - DateTime.parse(filtered[idx])).to_i }
end

# => [[4], [0, 10]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM