以下是软件版本号:

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

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


当前回答

我想为解决这个问题的轻量级库做广告:语义版本

可以同时使用面向对象(OO)和面向函数。它可以作为npm-package和现成的包文件使用。

其他回答

我根据Kons的想法做了这个,并针对Java版本“1.7.0_45”进行了优化。它只是一个将版本字符串转换为浮点数的函数。这是函数:

function parseVersionFloat(versionString) {
    var versionArray = ("" + versionString)
            .replace("_", ".")
            .replace(/[^0-9.]/g, "")
            .split("."),
        sum = 0;
    for (var i = 0; i < versionArray.length; ++i) {
        sum += Number(versionArray[i]) / Math.pow(10, i * 3);
    }
    console.log(versionString + " -> " + sum);
    return sum;
}

字符串“1.7.0_45”被转换为1.0070000450000001,这足以进行正常的比较。这里解释的错误:如何处理JavaScript中的浮点数精度?如果需要超过3个数字在任何部分,你可以改变除法数学。Pow (10, I * 3);;

输出如下所示:

1.7.0_45         > 1.007000045
ver 1.7.build_45 > 1.007000045
1.234.567.890    > 1.23456789

我想为解决这个问题的轻量级库做广告:语义版本

可以同时使用面向对象(OO)和面向函数。它可以作为npm-package和现成的包文件使用。

进行这种比较的基本思想是使用Array。拆分以从输入字符串中获得部件数组,然后比较两个数组中的部件对;如果部分不相等,我们就知道哪个版本更小。

这里有一些重要的细节需要记住:

每对零件应该如何比较?这个问题想要从数字上进行比较,但是如果我们有不只是由数字组成的版本字符串(例如。“1.0”)? 如果一个版本字符串的部分比另一个多,会发生什么?很可能“1.0”应该被认为小于“1.0.1”,但是“1.0.0”呢?

下面是你可以直接使用的实现代码(要点和文档):

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。这意味着它将不会在9之前的IE版本中运行。如果你需要支持这些方法,你就必须为缺失的方法提供填充。

看看这篇博客文章。此函数适用于数字版本号。

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
// Return 1 if a > b
// Return -1 if a < b
// Return 0 if a == b
function compare(a, b) {
    if (a === b) {
       return 0;
    }

    var a_components = a.split(".");
    var b_components = b.split(".");

    var len = Math.min(a_components.length, b_components.length);

    // loop while the components are equal
    for (var i = 0; i < len; i++) {
        // A bigger than B
        if (parseInt(a_components[i]) > parseInt(b_components[i])) {
            return 1;
        }

        // B bigger than A
        if (parseInt(a_components[i]) < parseInt(b_components[i])) {
            return -1;
        }
    }

    // If one's a prefix of the other, the longer one is greater.
    if (a_components.length > b_components.length) {
        return 1;
    }

    if (a_components.length < b_components.length) {
        return -1;
    }

    // Otherwise they are the same.
    return 0;
}

console.log(compare("1", "2"));
console.log(compare("2", "1"));

console.log(compare("1.0", "1.0"));
console.log(compare("2.0", "1.0"));
console.log(compare("1.0", "2.0"));
console.log(compare("1.0.1", "1.0"));