Основная идея для такого сравнения заключается в использовании Array.split
для получения массивов деталей из входных строк, а затем сравнения пар деталей из двух массивов;если части не равны, мы знаем, какая версия меньше.
Есть несколько важных деталей, о которых следует помнить:
- Как следует сравнивать части в каждой паре?Вопрос хочет сравнить численно, но что если у нас есть строки версий, которые не состоят только из цифр (например, «1.0a»)?
- Что должно произойти, если одна строка версии имеет больше частей, чем другая?Скорее всего, «1.0» следует считать меньше, чем «1.0.1», но как насчет «1.0.0»?
Вот код для реализации, которую вы можете использовать напрямую ( gistс документацией ):
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;
}
Эта версия сравнивает части естественно , не принимает суффиксы символов и считает "1.7" меньше, чем "1.7.0".Режим сравнения может быть изменен на лексикографический, а более короткие строки версии могут быть автоматически дополнены нулями, используя необязательный третий аргумент.
Существует JSFiddle, который запускает «модульные тесты» здесь ;это слегка расширенная версия работы ripper234 (спасибо).
Важное примечание: Этот код использует Array.map
и Array.every
, что означает, что он не будет работать в версиях IE более ранних, чем 9. Если вам потребуется их поддержка, вам придется предоставить полифиллы для отсутствующих методов.