如何比较Ruby中的版本?

时间:2022-07-18 22:47:50

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'.

例如:'0.1','0.2.1','0.44'。

8 个解决方案

#1


197  

Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')

#2


31  

If you need to check pessimistic version constraints, you can use Gem::Dependency like this:

如果需要检查悲观版本约束,可以使用Gem::Dependency, like this::

Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')

#3


19  

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')]

#4


15  

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

您可以使用版本管理gem (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

#5


9  

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.

或者做一些功能包装,如果你这么想的话。

#6


7  

Gem::Version is the easy way to go here:

版本是最简单的方法:

%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"

#7


3  

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.

本质上,您将每个版本字符串转换为一个整数数组,然后使用数组比较操作符。如果代码中有人需要维护的话,您可以分解组件步骤,使其更易于遵循。

#8


-1  

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

#1


197  

Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')

#2


31  

If you need to check pessimistic version constraints, you can use Gem::Dependency like this:

如果需要检查悲观版本约束,可以使用Gem::Dependency, like this::

Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')

#3


19  

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')]

#4


15  

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

您可以使用版本管理gem (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

#5


9  

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.

或者做一些功能包装,如果你这么想的话。

#6


7  

Gem::Version is the easy way to go here:

版本是最简单的方法:

%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"

#7


3  

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.

本质上,您将每个版本字符串转换为一个整数数组,然后使用数组比较操作符。如果代码中有人需要维护的话,您可以分解组件步骤,使其更易于遵循。

#8


-1  

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