¿Cómo escribir un fragmento de código para comparar algunas cadenas de versiones y obtener la más nueva?
Por ejemplo cadenas como: '0.1', '0.2.1', '0.44'
.
¿Cómo escribir un fragmento de código para comparar algunas cadenas de versiones y obtener la más nueva?
Por ejemplo cadenas como: '0.1', '0.2.1', '0.44'
.
Respuestas:
Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')
Gem::Version...
sintaxis me hizo pensar que necesitaría instalar una gema. Pero no fue necesario.
Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
require 'rubygems'
para obtener acceso al Gem
espacio de nombres. Sin embargo, a partir de la versión 1.9, se incluye automáticamente.
Si necesita verificar las restricciones de versión pesimista , puede usar Gem :: Dependency de esta manera:
Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
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')]
vers = (1..3000000).map{|x| "0.0.#{x}"}; 'ok' puts Time.now; vers.map{|v| ComparableVersion.new(v) }.sort.first; puts Time.now # 24 seconds 2013-10-29 13:36:09 -0700 2013-10-29 13:36:33 -0700 => nil puts Time.now; vers.map{|v| Gem::Version.new(v) }.sort.first; puts Time.now # 41 seconds 2013-10-29 13:36:53 -0700 2013-10-29 13:37:34 -0700
Code blob lo está haciendo feo, pero básicamente, usar esto vs Gem :: Version es aproximadamente el doble de rápido.
Puedes usar la Versionomy
gema (disponible en 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
yo lo haría
a1 = v1.split('.').map{|s|s.to_i}
a2 = v2.split('.').map{|s|s.to_i}
Entonces puedes hacer
a1 <=> a2
(y probablemente todas las demás comparaciones "habituales").
... y si quieres una prueba <
o >
, puedes hacer, por ejemplo,
(a1 <=> a2) < 0
o hacer un envoltorio más funcional si así lo desea.
Gem::Version
es la forma más fácil de ir aquí:
%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"
Si desea hacerlo a mano sin usar gemas, algo como lo siguiente debería funcionar, aunque tiene un aspecto un poco perverso.
versions = [ '0.10', '0.2.1', '0.4' ]
versions.map{ |v| (v.split '.').collect(&:to_i) }.max.join '.'
Básicamente, convierte cada cadena de versión en una matriz de enteros y luego usa el operador de comparación de matriz . Puede dividir los pasos de los componentes para obtener algo un poco más fácil de seguir si esto va en el código que alguien necesitará mantener.
Tuve el mismo problema, quería un comparador de versiones sin gemas, se me ocurrió esto:
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
Version
clase simple que hace todo lo que necesito: shorts.jeffkreeftmeijer.com/2014/…