У меня есть номер версии с 3 цифрами как Строка,
var version = "1.2.3";
и хотел бы сравнить его с другой версией. Видеть, является ли версия более новой, чем otherversion,
var otherVersion = "1.2.4";
Как Вы сделали бы это?
Псевдо:
.
(См. @arhorns answer для элегантной реализации)
Проблема большинства представленных версий в том, что они не могут обрабатывать любое количество частей версии (например, 1.4.2 ... 1.2 и т.д.) и/или у них есть требование, чтобы часть версии состояла из одной цифры, что на самом деле не так часто встречается.
Улучшенная функция compareVersions()
Эта функция возвращает 1, если v1 больше v2, -1, если v2 больше и 0, если версии равны (удобно для пользовательской сортировки)
Я не делаю никакой проверки ошибок на входах.
function compareVersions (v1, v2)
{
v1 = v1.split('.');
v2 = v2.split('.');
var longestLength = (v1.length > v2.length) ? v1.length : v2.length;
for (var i = 0; i < longestLength; i++) {
if (v1[i] != v2[i]) {
return (v1 > v2) ? 1 : -1
}
}
return 0;
}
Вы можете использовать следующую реализацию ( на основе решения jensgram ):
function isNewer(a, b) {
var partsA = a.split('.');
var partsB = b.split('.');
var numParts = partsA.length > partsB.length ? partsA.length : partsB.length;
var i;
for (i = 0; i < numParts; i++) {
if ((parseInt(partsB[i], 10) || 0) !== (parseInt(partsA[i], 10) || 0)) {
return ((parseInt(partsB[i], 10) || 0) > (parseInt(partsA[i], 10) || 0));
}
}
return false;
}
console.log(isNewer('1.2.3', '1.2.4')); // true
console.log(isNewer('1.2.3', '1.2.0')); // false
console.log(isNewer('1.2.3', '1.2.3.1')); // true
console.log(isNewer('1.2.3', '1.2.2.9')); // false
console.log(isNewer('1.2.3', '1.2.10')); // true
Обратите внимание, что использование parseInt ()
необходимо, потому что в противном случае последний тест return false
: «10»> «3»
возвращает false
.
Может быть вот так (на скорую руку)?
function isNewer(s0, s1) {
var v0 = s0.split('.'), v1 = s1.split('.');
var len0 = v0.length, len1=v1.length;
var temp0, temp1, idx = 0;
while (idx<len0) {
temp0 = parseInt(v0[idx], 10);
if (len1>idx) {
temp1 = parseInt(v1[idx], 10);
if (temp1>temp0) {return true;}
}
idx += 1;
}
if (parseInt(v0[idx-1], 10)>parseInt(v1[idx-1], 10)) {return false;}
return len1 > len0;
}
var version = "1.2.3";
var otherVersion = "1.2.4";
console.log('newer:'+(isNewer(version, otherVersion)));
Он заботится о разном количестве частей, но работает только с числами между точками.
Поскольку мне скучно, вот подход, похожий на нашу десятичную систему (десятки, сотни, тысячи и т.д.), который использует обратный вызов regex вместо цикла:
function compareVersion(a, b) {
var expr = /\d+/g, places = Math.max(a.split(expr).length, b.split(expr).length);
function convert(s) {
var place = Math.pow(100, places), total = 0;
s.replace(expr,
function (n) {
total += n * place;
place /= 100;
}
);
return total;
};
if (convert(a) > convert(b)) {
return a;
}
return b;
}
Он возвращает большую версию, например:
compareVersion('1.4', '1.3.99.32.60.4'); // => 1.4
С одним из операторов сравнения.
"1.2.3" > "1.2.4" //false
"1.2.3" < "1.2.4" //true
Если у вас действительно только одна цифра в каждой части, почему бы просто не использовать прямое сравнение?
>>> var version = "1.2.3"; var otherVersion = "1.2.4"; version < otherVersion
true
Кажется, это также работает с сокращенными версиями:
>>> '1.2' > '1.2.4'
false
>>> '1.3' > '1.2.4'
true
function VersionValue(var str)
{
var tmp = str.split('.');
return (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
}
if (VersionValue(version) > VersionValue(otherVersion))...
например
Обратите внимание, что ни одно из этих решений не вернет заведомо правильный результат для таких вещей, как 0.9beta
или 1.0 RC 1
. Однако в PHP это делается довольно интуитивно: http://de3.php.net/manual/en/function.version-compare.php , и есть порт JS для этого: http://phpjs.org/functions/version_compare (я не утверждаю, что это очень красиво или эффективно, просто «завершено»).