Come scrivere un pezzo di codice per confrontare alcune stringhe di versioni e ottenere la più recente?
Per esempio stringhe come: '0.1', '0.2.1', '0.44'
.
Come scrivere un pezzo di codice per confrontare alcune stringhe di versioni e ottenere la più recente?
Per esempio stringhe come: '0.1', '0.2.1', '0.44'
.
Risposte:
Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')
Gem::Version...
sintassi mi ha fatto pensare che avrei bisogno di installare una gemma. Ma non era richiesto.
Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
require 'rubygems'
per accedere allo Gem
spazio dei nomi. Dalla 1.9 in poi, tuttavia, è automaticamente incluso.
Se è necessario controllare i vincoli della versione pessimistica , è possibile utilizzare Gem :: Dependency in questo modo:
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
blob di codice lo rende brutto, ma fondamentalmente, usare questa versione rispetto a Gem :: è circa il doppio più veloce.
Puoi usare la Versionomy
gemma (disponibile su 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
farei
a1 = v1.split('.').map{|s|s.to_i}
a2 = v2.split('.').map{|s|s.to_i}
Allora puoi farlo
a1 <=> a2
(e probabilmente tutti gli altri "soliti" confronti).
... e se vuoi un test <
o >
, puoi fare ad es
(a1 <=> a2) < 0
o fai un po 'più di wrapping delle funzioni se sei così incline.
Gem::Version
è il modo più semplice per andare qui:
%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"
Se vuoi farlo a mano senza usare nessuna gemma, qualcosa come il seguente dovrebbe funzionare, anche se sembra un po 'perly.
versions = [ '0.10', '0.2.1', '0.4' ]
versions.map{ |v| (v.split '.').collect(&:to_i) }.max.join '.'
In sostanza, si trasforma ogni stringa di versione in una matrice di numeri interi e quindi si utilizza l' operatore di confronto di matrice . Potresti suddividere i passaggi dei componenti per ottenere qualcosa di un po 'più facile da seguire se questo sta andando in codice che qualcuno dovrà mantenere.
Ho avuto lo stesso problema, volevo un comparatore di versioni senza gemme, mi è venuto in mente questo:
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
classe che fa tutto ciò di cui avevo bisogno: shorts.jeffkreeftmeijer.com/2014/…