Wie schreibe ich einen Code, um einige Versionszeichenfolgen zu vergleichen und die neuesten zu erhalten?
Zum Beispiel Zeichenfolgen wie : '0.1', '0.2.1', '0.44'
.
Wie schreibe ich einen Code, um einige Versionszeichenfolgen zu vergleichen und die neuesten zu erhalten?
Zum Beispiel Zeichenfolgen wie : '0.1', '0.2.1', '0.44'
.
Antworten:
Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')
Gem::Version...
Syntax ließ mich denken, ich müsste ein Juwel installieren. Aber es war nicht erforderlich.
Gem::Dependency.new(nil, '~> 1.4.5').match?(nil, '1.4.6beta4')
require 'rubygems'
, um Zugriff auf den Gem
Namespace zu erhalten. Ab 1.9 ist es jedoch automatisch enthalten.
Wenn Sie pessimistische Versionsbeschränkungen überprüfen müssen , können Sie Gem :: Dependency wie folgt verwenden:
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 macht es hässlich, aber im Grunde ist die Verwendung dieser vs Gem :: Version etwa doppelt so schnell.
Sie können den Versionomy
Edelstein verwenden (erhältlich bei 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
Ich würde es tun
a1 = v1.split('.').map{|s|s.to_i}
a2 = v2.split('.').map{|s|s.to_i}
Dann können Sie tun
a1 <=> a2
(und wahrscheinlich alle anderen "üblichen" Vergleiche).
... und wenn Sie ein <
oder >
testen möchten , können Sie z
(a1 <=> a2) < 0
oder machen Sie noch etwas Funktionsumbruch, wenn Sie dazu neigen.
Gem::Version
ist der einfache Weg hierher zu gehen:
%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"
Wenn Sie es von Hand machen möchten, ohne Edelsteine zu verwenden, sollte etwas wie das Folgende funktionieren, obwohl es ein wenig perly aussieht.
versions = [ '0.10', '0.2.1', '0.4' ]
versions.map{ |v| (v.split '.').collect(&:to_i) }.max.join '.'
Im Wesentlichen wandeln Sie jede Versionszeichenfolge in ein Array von Ganzzahlen um und verwenden dann den Array-Vergleichsoperator . Sie können die Komponentenschritte aufteilen, um etwas leichter zu befolgen, wenn dies in Code enthalten ist, den jemand warten muss.
Ich hatte das gleiche Problem, ich wollte einen Versionskomparator ohne Edelsteine, und fand Folgendes:
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
Klasse, die alles tut, was ich brauche: shorts.jeffkreeftmeijer.com/2014/…