How to compare versions in Ruby?

前端 未结 8 1935
耶瑟儿~
耶瑟儿~ 2020-12-12 19:47

How to write a piece of code to compare some versions strings and get the newest?

For example strings like: \'0.1\', \'0.2.1\', \'0.44\'.

相关标签:
8条回答
  • 2020-12-12 20:30

    If you want to do it by hand without using any gems, something like the following should work, though it's a little perly looking.

    versions = [ '0.10', '0.2.1', '0.4' ]
    versions.map{ |v| (v.split '.').collect(&:to_i) }.max.join '.'
    

    Essentially, you turn each version string in to an array of integers and then use the array comparison operator. You could break out the component steps to get something a little easier to follow if this is going in code somebody will need to maintain.

    0 讨论(0)
  • 2020-12-12 20:33
    class Version < Array
      def initialize s
        super(s.split('.').map { |e| e.to_i })
      end
      def < x
        (self <=> x) < 0
      end
      def > x
        (self <=> x) > 0
      end
      def == x
        (self <=> x) == 0
      end
    end
    p [Version.new('1.2') < Version.new('1.2.1')]
    p [Version.new('1.2') < Version.new('1.10.1')]
    
    0 讨论(0)
  • 2020-12-12 20:33

    I would do

    a1 = v1.split('.').map{|s|s.to_i}
    a2 = v2.split('.').map{|s|s.to_i}
    

    Then you can do

    a1 <=> a2
    

    (and probably all the other "usual" comparisons).

    ...and if you want a < or > test, you can do e.g.

    (a1 <=> a2) < 0
    

    or do some more function wrapping if you're so inclined.

    0 讨论(0)
  • 2020-12-12 20:38
    Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')
    
    0 讨论(0)
  • 2020-12-12 20:38

    You can use the Versionomy gem (available at github):

    require 'versionomy'
    
    v1 = Versionomy.parse('0.1')
    v2 = Versionomy.parse('0.2.1')
    v3 = Versionomy.parse('0.44')
    
    v1 < v2  # => true
    v2 < v3  # => true
    
    v1 > v2  # => false
    v2 > v3  # => false
    
    0 讨论(0)
  • 2020-12-12 20:42

    I had the same problem, I wanted a Gem-less version comparator, came up with this:

    def compare_versions(versionString1,versionString2)
        v1 = versionString1.split('.').collect(&:to_i)
        v2 = versionString2.split('.').collect(&:to_i)
        #pad with zeroes so they're the same length
        while v1.length < v2.length
            v1.push(0)
        end
        while v2.length < v1.length
            v2.push(0)
        end
        for pair in v1.zip(v2)
            diff = pair[0] - pair[1]
            return diff if diff != 0
        end
        return 0
    end
    
    0 讨论(0)
提交回复
热议问题