1.0.0
と1.0.1
どっちが新しいバージョンなの?って比較しなきゃいけない時ってあると思うんです。でも、自前でやろうとすると案外面倒。でも、そこらに転がっている機能で実はできたりするので忘れないように書いておきます。
ドットを抜いて、無理やり数値化して比較すると、桁ズレ等で不幸になるので気をつけよう。
Ruby
Gem::Versionを使うとさくっと比較できる。内部の処理を見たら、けっこう参考になった。
Gem::Version.new('1.0.0') > Gem::Version.new('1.10.0')
#=> false
PHP
PHPにこんな関数あったんだシリーズに入りそうな感じ。それとも皆、常識だったんだろうか。
version_compare('1.0.0', '1.10.0');
#=> -1
version_compare('2.0.0', '1.10.0');
#=> 1
version_compare('1.10.0', '1.10.0');
#=> 0
Objective-C
[hoge compare:piyo options:NSNumericSearch]
で、PHPのversion_compare()
のように、-1 / 1 / 0 の値が返ってきます。NSOrderedAscendingなどで比較してあげればOK。
NSString *verA = @"1.0.0";
NSString *verB = @"1.10.0";
[verA compare:verB options:NSNumericSearch] == NSOrderedAscending
#=> true
[verA compare:verB options:NSNumericSearch] == NSOrderedDescending
#=> false
NSString *verA = @"1.10.0";
NSString *verB = @"1.10.0";
[verA compare:verB options:NSNumericSearch] == NSOrderedSame
#=> true
JavaScript
JavaScriptには、標準でそんな機能はなかったけど、作っている人がいたので紹介。
function versionCompare(v1, v2, options) {
var lexicographical = options && options.lexicographical,
zeroExtend = options && options.zeroExtend,
v1parts = v1.split('.'),
v2parts = v2.split('.');
function isValidPart(x) {
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
}
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
return NaN;
}
if (zeroExtend) {
while (v1parts.length < v2parts.length) v1parts.push("0");
while (v2parts.length < v1parts.length) v2parts.push("0");
}
if (!lexicographical) {
v1parts = v1parts.map(Number);
v2parts = v2parts.map(Number);
}
for (var i = 0; i < v1parts.length; ++i) {
if (v2parts.length == i) {
return 1;
}
if (v1parts[i] == v2parts[i]) {
continue;
}
else if (v1parts[i] > v2parts[i]) {
return 1;
}
else {
return -1;
}
}
if (v1parts.length != v2parts.length) {
return -1;
}
return 0;
}
Java
Java…には、あるんだろうか。謎。
SQL
SQL…も、やりようってあるのかな。