What is the best way to convert a Ruby string range to a Range object

后端 未结 8 2130
一生所求
一生所求 2020-12-29 23:38

I have some Ruby code which takes dates on the command line in the format:

-d 20080101,20080201..20080229,20080301

I want to run for all da

相关标签:
8条回答
  • 2020-12-29 23:49

    Here suppose you want to store the hash as a system constant value and fetch it in any model. The hash key will be a range value.

    hash_1 = {1..5 => 'a', 6..12 => 'b', 13..67 => 'c', 68..9999999 => 'd'}
    

    Then create the system constant with value as hash_1.to_json. .to_json will convert your hash object to JSON object. Now inside the code create a new hash hash_2,

    JSON.parse(SystemConstant.get('Constant_name')).each{|key,val| temp_k=key.split('..').map{|d| Integer(d)}; hash_2[temp_k[0]..temp_k[1]] = val}
    

    The new hash_2 will be the required hash_1

    0 讨论(0)
  • 2020-12-29 23:55

    Inject with no args works well for two element arrays:

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

    Of course, this can be made generic

    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
    
    0 讨论(0)
  • 2020-12-29 23:57

    Combining @Purfideas answer with another answer somewhere on StackOverflow, I solved this by also surrounding the code with an input check, so the only thing used is a valid enumerable

    if !value[/^[0-9]+\.\.[0-9]+$/].nil?
        ends = value.split('..').map{|d| Integer(d)}
        value = ends[0]..ends[1]
    end
    

    It essentially rewrites your string value to a enumerable value. This comes in handy if you add a enumerable field in a yaml config file.

    If you need it for your application, you could extend the regex with an optional third literal dot, that could be optional.

    0 讨论(0)
  • 2020-12-30 00:01
    Range.new(*self.split("..").map(&:to_i))
    
    0 讨论(0)
  • 2020-12-30 00:02

    Ranger uses regex to validate strings with no SQL injection fear, and then eval.

    0 讨论(0)
  • 2020-12-30 00:10

    But then just do

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

    anyway I don't recommend eval, for security reasons

    0 讨论(0)
提交回复
热议问题