以下是软件版本号:

"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"

这样可以更清楚地看到背后的想法。 但是,我怎样才能把它转换成计算机程序呢?


当前回答

这实际上取决于版本控制系统背后的逻辑。每个数字代表什么,如何使用。

每个subversion是否是一个用于指定开发阶段的数字? 为0 1代表β 发布候选2个 3为(最终)发布

它是构建版本吗?您是否应用增量更新?

一旦了解了版本控制系统的工作原理,创建算法就变得很容易了。

如果您不允许在每个subversion中使用大于9的数字,则删除所有小数,但第一个小数将允许您进行直接比较。

如果允许在任何一种颠覆版本中使用大于9的数字,有几种方法可以比较它们。最明显的方法是将字符串按小数分割,然后比较每一列。

但是在不知道版本控制系统是如何工作的情况下,当版本1.0.2a发布时,实现像上面这样的过程可能会很麻烦。

其他回答

一个非常简单的方法:

function compareVer(previousVersion, currentVersion) {
 try {
    const [prevMajor, prevMinor = 0, prevPatch = 0] = previousVersion.split('.').map(Number);
    const [curMajor, curMinor = 0, curPatch = 0] = currentVersion.split('.').map(Number);

    if (curMajor > prevMajor) {
      return 'major update';
    }
    if (curMajor < prevMajor) {
      return 'major downgrade';
    }
    if (curMinor > prevMinor) {
      return 'minor update';
    }
    if (curMinor < prevMinor) {
      return 'minor downgrade';
    }
    if (curPatch > prevPatch) {
      return 'patch update';
    }
    if (curPatch < prevPatch) {
      return 'patch downgrade';
    }
    return 'same version';
  } catch (e) {
    return 'invalid format';
  }
}

输出:

compareVer("3.1", "3.1.1") // patch update
compareVer("3.1.1", "3.2") // minor update
compareVer("2.1.1", "1.1.1") // major downgrade
compareVer("1.1.1", "1.1.1") // same version

这个非常小,但非常快的比较函数接受每个段的任何长度和任何数字大小的版本号。

返回值: -如果a < b,则数字< 0 -如果是> b,则为> 0 如果a = b - 0

所以你可以使用它作为array。sort()的比较函数;

编辑:修正了版本剥离尾随零识别“1”和“1.0.0”相等的错误

function cmpVersions (a, b) { var i, diff; var regExStrip0 = /(\.0+)+$/; var segmentsA = a.replace(regExStrip0, '').split('.'); var segmentsB = b.replace(regExStrip0, '').split('.'); var l = Math.min(segmentsA.length, segmentsB.length); for (i = 0; i < l; i++) { diff = parseInt(segmentsA[i], 10) - parseInt(segmentsB[i], 10); if (diff) { return diff; } } return segmentsA.length - segmentsB.length; } // TEST console.log( ['2.5.10.4159', '1.0.0', '0.5', '0.4.1', '1', '1.1', '0.0.0', '2.5.0', '2', '0.0', '2.5.10', '10.5', '1.25.4', '1.2.15'].sort(cmpVersions)); // Result: // ["0.0.0", "0.0", "0.4.1", "0.5", "1.0.0", "1", "1.1", "1.2.15", "1.25.4", "2", "2.5.0", "2.5.10", "2.5.10.4159", "10.5"]

我们的想法是比较两个版本,并知道哪个是最大的。我们删除“。”,并将向量的每个位置与其他位置进行比较。

// 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.0.0b3)

const compareVer = ((prep, repl) =>
{
  prep = t => ("" + t)
      //treat non-numerical characters as lower version
      //replacing them with a negative number based on charcode of first character
    .replace(/[^0-9\.]+/g, c => "." + (c.replace(/[\W_]+/, "").toLowerCase().charCodeAt(0) - 65536) + ".")
      //remove trailing "." and "0" if followed by non-numerical characters (1.0.0b);
    .replace(/(?:\.0+)*(\.-[0-9]+)(\.[0-9]+)?\.*$/g, "$1$2")
    .split('.');

  return (a, b, c, i, r) =>
  {
    a = prep(a);
    b = prep(b);
    for (i = 0, r = 0, c = Math.max(a.length, b.length); !r && i++ < c;)
    {
      r = -1 * ((a[i] = ~~a[i]) < (b[i] = ~~b[i])) + (a[i] > b[i]);
    }
    return r;
  }
})();

函数返回:

如果a = b则为0

1如果a > b

-1如果a < b

1.0         = 1.0.0.0.0.0
1.0         < 1.0.1
1.0b1       < 1.0
1.0b        = 1.0b
1.1         > 1.0.1b
1.1alpha    < 1.1beta
1.1rc1      > 1.1beta
1.1rc1      < 1.1rc2
1.1.0a1     < 1.1a2
1.1.0a10    > 1.1.0a1
1.1.0alpha  = 1.1a
1.1.0alpha2 < 1.1b1
1.0001      > 1.00000.1.0.0.0.01

/*use strict*/ const compareVer = ((prep, repl) => { prep = t => ("" + t) //treat non-numerical characters as lower version //replacing them with a negative number based on charcode of first character .replace(/[^0-9\.]+/g, c => "." + (c.replace(/[\W_]+/, "").toLowerCase().charCodeAt(0) - 65536) + ".") //remove trailing "." and "0" if followed by non-numerical characters (1.0.0b); .replace(/(?:\.0+)*(\.-[0-9]+)(\.[0-9]+)?\.*$/g, "$1$2") .split('.'); return (a, b, c, i, r) => { a = prep(a); b = prep(b); for (i = 0, r = 0, c = Math.max(a.length, b.length); !r && i++ < c;) { r = -1 * ((a[i] = ~~a[i]) < (b[i] = ~~b[i])) + (a[i] > b[i]); } return r; } })(); //examples let list = [ ["1.0", "1.0.0.0.0.0"], ["1.0", "1.0.1"], ["1.0b1", "1.0"], ["1.0b", "1.0b"], ["1.1", "1.0.1b"], ["1.1alpha", "1.1beta"], ["1.1rc1", "1.1beta"], ["1.1rc1", "1.1rc2"], ["1.1.0a1", "1.1a2"], ["1.1.0a10", "1.1.0a1"], ["1.1.0alpha", "1.1a"], ["1.1.0alpha2", "1.1b1"], ["1.0001", "1.00000.1.0.0.0.01"] ] for(let i = 0; i < list.length; i++) { console.log( list[i][0] + " " + "<=>"[compareVer(list[i][0], list[i][1]) + 1] + " " + list[i][1] ); }

https://jsfiddle.net/vanowm/p7uvtbor/

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