Как сравнить номер версии программного обеспечения с помощью js? (только номер) - PullRequest
142 голосов
/ 26 июля 2011

Вот номер версии программного обеспечения:

"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"

Как я могу сравнить это? Предположим, правильный порядок:

"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"

Идея проста ...: Читайте первую цифру, затем, вторую, после этого третью .... Но я не могу преобразовать номер версии в число с плавающей точкой .... Вы также можете увидеть номер версии следующим образом:

"1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1.0"

и это более ясно, чтобы понять, в чем идея ... Но как преобразовать его в компьютерную программу? У кого-нибудь есть идеи о том, как это отсортировать? Спасибо.

Ответы [ 38 ]

3 голосов
/ 07 ноября 2017

2017 ответ:

v1 = '20.0.12'; 
v2 = '3.123.12';

compareVersion(v1,v2) // return true

function compareVersion(ver1, ver2) {
        ver1 = ver1.split('.')
        ver2 = ver2.split('.')
        var i = 0, v1, v2;
        ver1 = Array.isArray(ver1) ? ver1 : [ver1];
        /*default is true*/
        while (i < 4) {
            v1 = ver1[i]; v2 = ver2[i];
            if (!v1 || !v2) return true;
            if (v1 * 1 < v2 * 1) return false;
            i++;
        }
        return true;
    }

Более крутой ответ для браузера, который не поддерживает IE (озеро padStart):

 function compareVersion2(ver1, ver2) {
      ver1 = ver1.split('.').map( s => s.padStart(10) ).join('.');
      ver2 = ver2.split('.').map( s => s.padStart(10) ).join('.');
      return ver1 <= ver2;
 }

Идея здесь состоит в том, чтобы сравнить число, но в формате строки.чтобы сравнение было правильным и простым, два числа / строки должны иметь одинаковую длину

Например:

"123" > "99" // return false, but it wrong "123" "> "099" // but padding the short number with zeros make the comparision to be right

Таким образом, идея решения состоит в том, чтобызаполнить все части версии нулями, чтобы все числа были одинаковой ширины 10. затем соедините все строки вместе.поэтому в одном сравнении для всей строки мы получим правильный ответ.

Например:

var ver1 = '0.2.10', ver2=`0.10.2`
//become 
ver1 = '0000000000.0000000002.0000000010'
ver2 = '0000000000.0000000010.0000000002'
// then it easy to see that
ver1 <= ver2 // true
2 голосов
/ 10 декабря 2013

Вот реализация coffeescript, подходящая для использования с Array.sort, вдохновленная другими ответами здесь:

# Returns > 0 if v1 > v2 and < 0 if v1 < v2 and 0 if v1 == v2
compareVersions = (v1, v2) ->
  v1Parts = v1.split('.')
  v2Parts = v2.split('.')
  minLength = Math.min(v1Parts.length, v2Parts.length)
  if minLength > 0
    for idx in [0..minLength - 1]
      diff = Number(v1Parts[idx]) - Number(v2Parts[idx])
      return diff unless diff is 0
  return v1Parts.length - v2Parts.length
2 голосов
/ 26 ноября 2017
// Returns true if v1 is bigger than v2, and false if otherwise.
function isNewerThan(v1, v2) {
      v1=v1.split('.');
      v2=v2.split('.');
      for(var i = 0; i<Math.max(v1.length,v2.length); i++){
        if(v1[i] == undefined) return false; // If there is no digit, v2 is automatically bigger
        if(v2[i] == undefined) return true; // if there is no digit, v1 is automatically bigger
        if(v1[i] > v2[i]) return true;
        if(v1[i] < v2[i]) return false;
      }
      return false; // Returns false if they are equal
    }
1 голос
/ 28 марта 2019

Мой менее подробный ответ, чем большинство ответов здесь

/**
 * Compare two semver versions. Returns true if version A is greater than
 * version B
 * @param {string} versionA
 * @param {string} versionB
 * @returns {boolean}
 */
export const semverGreaterThan = function(versionA, versionB){
  var versionsA = versionA.split(/\./g),
    versionsB = versionB.split(/\./g)
  while (versionsA.length || versionsB.length) {
    var a = Number(versionsA.shift()), b = Number(versionsB.shift())
    if (a == b)
      continue
    return (a > b || isNaN(b))
  }
  return false
}
1 голос
/ 17 марта 2016

Идея состоит в том, чтобы сравнить две версии и знать, какая из них самая большая. Мы удаляем "." и мы сравниваем каждую позицию вектора с другой.

// Return 1  if a > b
// Return -1 if a < b
// Return 0  if a == b

function compareVersions(a_components, b_components) {

   if (a_components === b_components) {
       return 0;
   }

   var partsNumberA = a_components.split(".");
   var partsNumberB = b_components.split(".");

   for (var i = 0; i < partsNumberA.length; i++) {

      var valueA = parseInt(partsNumberA[i]);
      var valueB = parseInt(partsNumberB[i]);

      // A bigger than B
      if (valueA > valueB || isNaN(valueB)) {
         return 1;
      }

      // B bigger than A
      if (valueA < valueB) {
         return -1;
      }
   }
}
1 голос
/ 23 декабря 2015

Это работает для числовых версий любой длины, разделенных точкой. Он возвращает true только в том случае, если myVersion> >imumVersion>, предполагая, что версия 1 меньше 1.0, версия 1.1 меньше 1.1.0 и так далее. Должно быть довольно просто добавить дополнительные условия, такие как принятие чисел (просто преобразовать в строку) и шестнадцатеричное или динамический разделитель (просто добавьте параметр разделителя, затем замените «.» На параметр)

function versionCompare(myVersion, minimumVersion) {

    var v1 = myVersion.split("."), v2 = minimumVersion.split("."), minLength;   

    minLength= Math.min(v1.length, v2.length);

    for(i=0; i<minLength; i++) {
        if(Number(v1[i]) > Number(v2[i])) {
            return true;
        }
        if(Number(v1[i]) < Number(v2[i])) {
            return false;
        }           
    }

    return (v1.length >= v2.length);
}

Вот несколько тестов:

console.log(versionCompare("4.4.0","4.4.1"));
console.log(versionCompare("5.24","5.2"));
console.log(versionCompare("4.1","4.1.2"));
console.log(versionCompare("4.1.2","4.1"));
console.log(versionCompare("4.4.4.4","4.4.4.4.4"));
console.log(versionCompare("4.4.4.4.4.4","4.4.4.4.4"));
console.log(versionCompare("0","1"));
console.log(versionCompare("1","1"));
console.log(versionCompare("","1"));
console.log(versionCompare("10.0.1","10.1"));

В качестве альтернативы вот рекурсивная версия

function versionCompare(myVersion, minimumVersion) {
  return recursiveCompare(myVersion.split("."),minimumVersion.split("."),Math.min(myVersion.length, minimumVersion.length),0);
}

function recursiveCompare(v1, v2,minLength, index) {
  if(Number(v1[index]) < Number(v2[index])) {
    return false;
  }
  if(Number(v1[i]) < Number(v2[i])) {
    return true;
    }
  if(index === minLength) {
    return (v1.length >= v2.length);
  }
  return recursiveCompare(v1,v2,minLength,index+1);
}
1 голос
/ 26 июля 2011

Функция replace() заменяет только первое вхождение в строке.Итак, давайте заменим . на ,.После этого удалите все . и снова введите значения , в . и проанализируйте их как плавающие.

for(i=0; i<versions.length; i++) {
    v = versions[i].replace('.', ',');
    v = v.replace(/\./g, '');
    versions[i] = parseFloat(v.replace(',', '.'));
}

наконец, сортируйте:

versions.sort();
1 голос
/ 26 мая 2012

Проверьте это сообщение в блоге . Эта функция работает для числовых номеров версий.

function compVersions(strV1, strV2) {
  var nRes = 0
    , parts1 = strV1.split('.')
    , parts2 = strV2.split('.')
    , nLen = Math.max(parts1.length, parts2.length);

  for (var i = 0; i < nLen; i++) {
    var nP1 = (i < parts1.length) ? parseInt(parts1[i], 10) : 0
      , nP2 = (i < parts2.length) ? parseInt(parts2[i], 10) : 0;

    if (isNaN(nP1)) { nP1 = 0; }
    if (isNaN(nP2)) { nP2 = 0; }

    if (nP1 != nP2) {
      nRes = (nP1 > nP2) ? 1 : -1;
      break;
    }
  }

  return nRes;
};

compVersions('10', '10.0'); // 0
compVersions('10.1', '10.01.0'); // 0
compVersions('10.0.1', '10.0'); // 1
compVersions('10.0.1', '10.1'); // -1
1 голос
/ 26 января 2013

Если, например, мы хотим проверить, если текущая версия jQuery меньше 1,8, parseFloat($.ui.version) < 1.8 ) выдаст неправильный результат, если версия "1.10.1", так как parseFloat ("1.10.1 ") возвращает 1.1.Сравнение строк также может быть неправильным, поскольку "1.8" < "1.10" оценивается как false.

Поэтому нам нужен такой тест

if(versionCompare($.ui.version, "1.8") < 0){
    alert("please update jQuery");
}

Следующая функция обрабатывает это правильно:

/** Compare two dotted version strings (like '10.2.3').
 * @returns {Integer} 0: v1 == v2, -1: v1 < v2, 1: v1 > v2
 */
function versionCompare(v1, v2) {
    var v1parts = ("" + v1).split("."),
        v2parts = ("" + v2).split("."),
        minLength = Math.min(v1parts.length, v2parts.length),
        p1, p2, i;
    // Compare tuple pair-by-pair. 
    for(i = 0; i < minLength; i++) {
        // Convert to integer if possible, because "8" > "10".
        p1 = parseInt(v1parts[i], 10);
        p2 = parseInt(v2parts[i], 10);
        if (isNaN(p1)){ p1 = v1parts[i]; } 
        if (isNaN(p2)){ p2 = v2parts[i]; } 
        if (p1 == p2) {
            continue;
        }else if (p1 > p2) {
            return 1;
        }else if (p1 < p2) {
            return -1;
        }
        // one operand is NaN
        return NaN;
    }
    // The longer tuple is always considered 'greater'
    if (v1parts.length === v2parts.length) {
        return 0;
    }
    return (v1parts.length < v2parts.length) ? -1 : 1;
}

Вот несколько примеров:

// compare dotted version strings
console.assert(versionCompare("1.8",      "1.8.1")    <   0);
console.assert(versionCompare("1.8.3",    "1.8.1")    >   0);
console.assert(versionCompare("1.8",      "1.10")     <   0);
console.assert(versionCompare("1.10.1",   "1.10.1")   === 0);
// Longer is considered 'greater'
console.assert(versionCompare("1.10.1.0", "1.10.1")   >   0);
console.assert(versionCompare("1.10.1",   "1.10.1.0") <   0);
// Strings pairs are accepted
console.assert(versionCompare("1.x",      "1.x")      === 0);
// Mixed int/string pairs return NaN
console.assert(isNaN(versionCompare("1.8", "1.x")));
//works with plain numbers
console.assert(versionCompare("4", 3)   >   0);

См. Здесь живой образец и набор тестов: http://jsfiddle.net/mar10/8KjvP/

1 голос
/ 28 февраля 2017

Я нахожу самый простой способ сравнить их, не уверен, что это то, что вы хотите.когда я запускаю приведенный ниже код в консоли, это имеет смысл, и используя метод sort (), я могу получить отсортированный массив строк версий.основан на алфавитном порядке.

"1.0" < "1.0.1" //true
var arr = ["1.0.1", "1.0", "3.2.0", "1.3"]
arr.sort();     //["1.0", "1.0.1", "1.3", "3.2.0"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...