Получить номер версии из String в Javascript? - PullRequest
6 голосов
/ 11 мая 2010

У меня есть номер версии с 3 цифрами в виде строки,

var version = "1.2.3";

и хотел бы сравнить его с другой версией. Чтобы узнать, является ли версия более новой, чем otherversion,

var otherVersion = "1.2.4";

Как бы вы это сделали?

Ответы [ 11 ]

8 голосов
/ 11 мая 2010

Псевдо:

  • Разделить оба на .
  • Сравнение деталей последовательно: Major -> Minor -> Rev (если деталь существует для обеих версий).
  • Если oV [n]> v [n]: oV наибольшее.
  • Остальное: Сравнить следующую часть.

(см. @Arhorns ответ для элегантной реализации)

6 голосов
/ 11 мая 2010

Проблема с большинством представленных версий заключается в том, что они не могут обрабатывать любое количество частей версии (например, 1.4.2 .. 1.2 и т. Д.) И / или они требуют, чтобы часть версии была одной цифрой, на самом деле не так часто.

Улучшена функция сравнения версий ()

Эта функция вернет 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; 
 }
4 голосов
/ 11 мая 2010

Вы можете использовать следующую реализацию ( на основе решения 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() необходимо, потому что в противном случае последний тест вернул бы false: "10" > "3" возвращает false.

3 голосов
/ 11 мая 2010

Если на самом деле у вас есть только одна цифра в каждой части, почему бы просто не использовать прямое сравнение?

>>> 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
1 голос
/ 12 сентября 2013

Я не смог найти ответ, который возвращает 1, 0 или -1 и заботится о конечных .0 и двухзначных партиалах, так что здесь идет. Это должно поддерживать все случаи, когда все частичные являются числами (см. Тесты внизу).

/*
 * Returns 1 if v1 is newer, -1 if v2 is newer and 0 if they are equal.
 * .0s at the end of the version will be ignored.
 *
 * If a version evaluates to false it will be treated as 0.
 *
 * Examples:
 * compareVersions ("2.0", "2") outputs 0,
 * compareVersions ("2.0.1", "2") outputs 1,
 * compareVersions ("0.2", "0.12.1") outputs -1,
 *
 */
function compareVersions (version1, version2) {
  var version1 = version1 ? version1.split('.') : ['0'],
      version2 = version2 ? version2.split('.') : ['0'],
      longest = Math.max(version1.length, version2.length);

  for (var i = 0; i < longest; i++) {
    /*
     * Convert to ints so that we can compare two digit parts
     * properly. (Otherwise would "2" be greater than "12").
     *
     * This returns NaN if the value is undefined, so we check for
     * NaN later.
     */
    var v1Part = parseInt(version1[i]),
        v2Part = parseInt(version2[i]);

    if (v1Part != v2Part) {

      // version2 is longer
      if (isNaN(v1Part)) {
        /*
         * Go through the rest of the parts of version 2. If it is only zeros,
         * consider the versions equal, otherwise consider version 2 as newer.
         */
        for (var j = i; j < longest; j++) {
          if (parseInt(version2[j]) != 0) return -1;
        }

      // version1 is longer
      } else if (isNaN(v2Part)) {
        for (var j = i; j < longest; j++) {
          if (parseInt(version1[j]) != 0) return 1;
        }

      // versions are equally long
      } else {
        return (v1Part > v2Part) ? 1 : -1;
      }
      return 0;
    }
  }
  return 0;
}

console.log(compareVersions("1", "1") === 0);
console.log(compareVersions("1.1", "1") === 1);
console.log(compareVersions("1.1.1", "1") === 1);
console.log(compareVersions("1", "1.1.1") === -1);
console.log(compareVersions("0.3", "0.3.0.0.1") === -1);
console.log(compareVersions("0.3", "0.3.0") === 0);
console.log(compareVersions("0.3.0.0.1", "0.3") === 1);
console.log(compareVersions("0.3.0", "0.3") === 0);
console.log(compareVersions("0.12", "0.2") === 1);
console.log(compareVersions("0.2", "0.12") === -1);
console.log(compareVersions("0.12.0", "0.2") === 1);
console.log(compareVersions("0.02.0", "0.2") === 0);
console.log(compareVersions("0.01.0", "0.2") === -1);
1 голос
/ 14 марта 2011
function isCorrectVersion(used,required){
    var used = parseFloat("0."+used.replace(/\./gi,""));
    var required = parseFloat("0."+required.replace(/\./gi,""));

    return (used < required) ? false : true;
}

Я использую это для сравнения функций jQuery, и, похоже, он работает нормально, сравнивая, например, 1.4 с 1.4.1 или 1.4.1 с 1.4.11.

1 голос
/ 11 мая 2010

Поскольку мне скучно, вот подход, аналогичный нашей десятичной системе (десятки, сотни, тысячи и т. Д.), Который использует обратный вызов регулярного выражения вместо цикла:

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;
}

Возвращает большую версию, например ::1004

compareVersion('1.4', '1.3.99.32.60.4'); // => 1.4
1 голос
/ 11 мая 2010
function VersionValue(var str)
{
var tmp = str.split('.');
return (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
}

if (VersionValue(version) > VersionValue(otherVersion))...

например

0 голосов
/ 11 мая 2010

Обратите внимание, что ни одно из этих решений сознательно не даст правильный результат для таких вещей, как 0.9beta или 1.0 RC 1. Тем не менее, он обрабатывается в PHP довольно интуитивно: http://de3.php.net/manual/en/function.version-compare.php, и есть порт JS этого: http://phpjs.org/functions/version_compare (я не утверждаю, что это очень красиво или эффективно, просто полный ').

0 голосов
/ 11 мая 2010

Может, вот так (быстро)?

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)));

Он заботится о различном количестве частей, но работает только с числами между точками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...