Wie schreibe ich ein Stück Code, um einige Versionen Strings zu vergleichen und das neueste zu bekommen?Wie vergleicht man Versionen in Ruby?
Zum Beispiel Strings wie: '0.1', '0.2.1', '0.44'
.
Wie schreibe ich ein Stück Code, um einige Versionen Strings zu vergleichen und das neueste zu bekommen?Wie vergleicht man Versionen in Ruby?
Zum Beispiel Strings wie: '0.1', '0.2.1', '0.44'
.
Sie können das Versionomy
gem (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 habe das gesehen, aber ich muss 2 Edelsteine verwenden, um eine wirklich einfache Sache zu machen. Ich möchte das als letzte Wahl verwenden. – user239895
"Erfinden Sie das Rad nicht neu". Weil es einfach ist, bedeutet das nicht, dass der Programmierer keine Arbeit und Gedanken in das Programm gesteckt hat. Nutze das Juwel, lies den Code und lerne daraus - und mach weiter mit größeren und besseren Dingen! – Trevoke
Dependency Management und Versionsverwaltung ist ein schwieriges Problem, wahrscheinlich viel schwieriger als die Aufgabe, 2 Versionen zu vergleichen. Ich stimme völlig zu, dass die Einführung von zwei weiteren Abhängigkeiten in diesem Fall der letzte Ausweg sein sollte. – kkodev
I
a1 = v1.split('.').map{|s|s.to_i}
a2 = v2.split('.').map{|s|s.to_i}
tun würde, dann können Sie tun
a1 <=> a2
(und wahrscheinlich alle anderen "übliche" Vergleiche).
... und wenn Sie einen <
oder >
Test möchten, können Sie z.B.
(a1 <=> a2) < 0
oder machen Sie weitere Funktionen, wenn Sie so geneigt sind.
Array.class_eval {include Comparable} lässt alle Arrays auf <, > usw. reagieren. Oder wenn Sie das nur mit bestimmten Arrays machen wollen: a = [1, 2]; a.extend (Vergleichbar) –
Cool, danke!(15 Zeichen) –
Das Problem, das ich mit dieser Lösung fand, ist, dass es zurückgibt, dass "1.2.0" größer ist als "1.2" –
Wenn Sie es von Hand tun möchten, ohne irgendwelche Edelsteine zu verwenden, sollte etwas wie das Folgende funktionieren, obwohl es ein bisschen perlig aussieht.
versions = [ '0.10', '0.2.1', '0.4' ]
versions.map{ |v| (v.split '.').collect(&:to_i) }.max.join '.'
Im Wesentlichen Sie jede Version String drehen in einem Array von ganzen Zahlen und dann die array comparison operator verwenden. Sie könnten die Komponentenschritte durchbrechen, um etwas leichter zu folgen, wenn dies in Code geht, den jemand pflegen muss.
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')]
Wie einige der anderen Antworten hier, sieht es so aus, als würden Sie String-Vergleiche statt Dies wird Probleme beim Vergleich von Versionen wie '0.10' und '0.4' verursachen. –
Guter Punkt; jetzt behoben. – DigitalRoss
Upvoted für präzise Lösung, die keine Installation eines Edelsteins erfordert. –
Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')
Die 'Gem :: Version ...' Syntax ließ mich denken, dass ich einen Edelstein installieren müsste. Aber es war nicht erforderlich. – Guillaume
Hinweis: Dies gibt einen Fehler über undefinierte Variable 'Gem' für mich auf Ruby 1.x, aber funktioniert wie erwartet auf Ruby 2.x. In meinem Fall habe ich RUBY_VERSION gegen Ruby 1.x (nicht 2.x) geprüft, also habe ich RUBY_VERSION.split ('.') [0] == "1" wie John Hyland und DigitalRoss gemacht. – uliwitness
'Gem :: Dependency.new (null, '~> 1.4.5') .match? (Null, '1.4.6beta4')' – levinalex
Gem::Version
ist der einfache Weg, hier gehen:
%w<0.1 0.2.1 0.44>.map {|v| Gem::Version.new v}.max.to_s
=> "0.44"
Viel besser als Versionomy, die eine c-Erweiterung benötigt !? –
Ich glaube nicht, dass 'max' funktioniert .. es wird 0,5 als größer als 0,44 gemeldet. Was beim Vergleich von sverver-Versionen nicht zutrifft. –
Dies scheint in der neuesten Gem :: Version behoben worden zu sein. 0,44 wird jetzt korrekt als höher als 0,5 angegeben. –
Wenn Sie pessimistic version constraints überprüfen müssen, Sie Gem::Dependency wie diese verwenden:
Gem::Dependency.new('', '~> 1.4.5').match?('', '1.4.6beta4')
Neuere Versionen scheinen eine Zeichenfolge für den Namen zu benötigen. Ein leerer String funktioniert einwandfrei, d. H. "Gem :: Dependency.new ('', '~> 1.4.5'). Match? ('', '1.4.6beta4')' –
danke. aktualisierte die Antwort. – levinalex
ich hatte Das gleiche Problem, ich wollte eine Gem-less Version Komparator, kam mit dieser:
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
Gute Frage! – Robert
Ich musste vor einiger Zeit pessimistische Versionsbeschränkungen vergleichen, aber ich wollte nicht auf RubyGems angewiesen sein, um dies zu tun, also schrieb ich eine einfache 'Version'-Klasse, die alles was ich brauche: http://shorts.jeffkreeftmeijer.com/2014/compare-version-numbers-with-pessimistische-constraints/ – jkreeftmeijer