Как написать фрагмент кода для сравнения строк версий и получения новейших?
Например, строки типа: '0.1', '0.2.1', '0.44'
.
Как написать фрагмент кода для сравнения строк версий и получения новейших?
Например, строки типа: '0.1', '0.2.1', '0.44'
.
Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')
Если вам нужно проверить пессимистические ограничения версий, вы можете использовать Gem:: Dependency следующим образом:
Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
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')]
Вы можете использовать Versionomy
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
Я бы сделал
a1 = v1.split('.').map{|s|s.to_i}
a2 = v2.split('.').map{|s|s.to_i}
Затем вы можете сделать
a1 <=> a2
(и, возможно, все остальные "обычные" сравнения).
... и если вам нужен тест <
или >
, вы можете сделать, например,
(a1 <=> a2) < 0
или сделайте еще несколько оберток функций, если вы так склонны.
Gem::Version
- это простой способ:
%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"
Если вы хотите сделать это вручную, не используя какие-либо драгоценные камни, что-то вроде следующего должно работать, хотя оно немного выглядит.
versions = [ '0.10', '0.2.1', '0.4' ]
versions.map{ |v| (v.split '.').collect(&:to_i) }.max.join '.'
По существу, вы переводите каждую строку версии в массив целых чисел, а затем используйте оператор сравнения массива. Вы можете выполнить шаги компонента, чтобы получить что-то немного легче, если это произойдет в коде, который кому-то нужно будет поддерживать.
У меня была такая же проблема, мне нужен компилятор версии Gem-less, придумал следующее:
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