将Ruby字符串范围转换为Range对象的最佳方法

时间:2020-03-05 18:50:32  来源:igfitidea点击:

我有一些Ruby代码,这些代码在命令行上采用以下格式的日期:

-d 20080101,20080201..20080229,20080301

这意味着我要运行20080201和20080229(包括)之间的所有日期以及列表中存在的其他日期。

给定我可以获得字符串20080201..20080229的最佳方法是将其转换为Range的实例。目前,我正在使用eval,但感觉应该有更好的方法。

@Purfideas我正在寻找一个更通用的答案,将int..int类型的任何字符串转换为我猜到的Range。

解决方案

回答

假设我们希望范围在数月之内正确迭代,请尝试

require 'date'

ends = '20080201..20080229'.split('..').map{|d| Date.parse(d)}
(ends[0]..ends[1]).each do |d|
  p d.day
end

回答

但是然后做

ends = '20080201..20080229'.split('..').map{|d| Integer(d)}
ends[0]..ends[1]

无论如何,出于安全考虑,我不建议评估

回答

不使用args的注入对于两个元素数组效果很好:

rng='20080201..20080229'.split('..').inject { |s,e| s.to_i..e.to_i }

当然,可以将其设为通用

class Range
  def self.from_ary(a)
    a.inject{|s,e| s..e }
  end
end

rng = Range.from_ary('20080201..20080229'.split('..').map{|s| s.to_i})
rng.class  # => Range

回答

Range.new(*self.split("..").map(&:to_i))