以下是软件版本号:

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

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


当前回答

摘自http://java.com/js/deployJava.js:

    // return true if 'installed' (considered as a JRE version string) is
    // greater than or equal to 'required' (again, a JRE version string).
    compareVersions: function (installed, required) {

        var a = installed.split('.');
        var b = required.split('.');

        for (var i = 0; i < a.length; ++i) {
            a[i] = Number(a[i]);
        }
        for (var i = 0; i < b.length; ++i) {
            b[i] = Number(b[i]);
        }
        if (a.length == 2) {
            a[2] = 0;
        }

        if (a[0] > b[0]) return true;
        if (a[0] < b[0]) return false;

        if (a[1] > b[1]) return true;
        if (a[1] < b[1]) return false;

        if (a[2] > b[2]) return true;
        if (a[2] < b[2]) return false;

        return true;
    }

其他回答

进行这种比较的基本思想是使用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版本中运行。如果你需要支持这些方法,你就必须为缺失的方法提供填充。

这是一个巧妙的技巧。如果您正在处理数值,在特定的值范围内,您可以为版本对象的每个级别分配一个值。例如,“largestValue”在这里被设置为0xFF,这为您的版本控制创建了一个非常“IP”的外观。

这也处理字母-数字版本(即1.2a < 1.2b)

// The version compare function
function compareVersion(data0, data1, levels) {
    function getVersionHash(version) {
        var value = 0;
        version = version.split(".").map(function (a) {
            var n = parseInt(a);
            var letter = a.replace(n, "");
            if (letter) {
                return n + letter[0].charCodeAt() / 0xFF;
            } else {
                return n;
            }
        });
        for (var i = 0; i < version.length; ++i) {
            if (levels === i) break;
            value += version[i] / 0xFF * Math.pow(0xFF, levels - i + 1);
        }
        return value;
    };
    var v1 = getVersionHash(data0);
    var v2 = getVersionHash(data1);
    return v1 === v2 ? -1 : v1 > v2 ? 0 : 1;
};
// Returns 0 or 1, correlating to input A and input B
// Direct match returns -1
var version = compareVersion("1.254.253", "1.254.253a", 3);

2017答:

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

compareVersions(v1,v2) 
// return positive: v1 > v2, zero:v1 == v2, negative: v1 < v2 
function compareVersions(v1, v2) {
        v1= v1.split('.')
        v2= v2.split('.')
        var len = Math.max(v1.length,v2.length)
        /*default is true*/
        for( let i=0; i < len; i++)
            v1 = Number(v1[i] || 0);
            v2 = Number(v2[i] || 0);
            if (v1 !== v2) return v1 - v2 ;
            i++;
        }
        return 0;
    }

最简单的现代浏览器代码:

 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"变成"123" > "099" 填充短数字“修复”比较

这里我用0填充每个部分,长度为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

你可以遍历每个以句点分隔的字符并将其转换为int类型:

var parts = versionString.split('.');

for (var i = 0; i < parts.length; i++) {
  var value = parseInt(parts[i]);
  // do stuffs here.. perhaps build a numeric version variable?
}

原谅我,如果这个想法已经访问在一个链接我没有看到。

我已经有了一些成功的部分转换成一个加权和像这样:

partSum = this.major * Math.Pow(10,9);
partSum += this.minor * Math.Pow(10, 6);
partSum += this.revision * Math.Pow(10, 3);
partSum += this.build * Math.Pow(10, 0);

这使得比较非常容易(比较double)。 我们的版本字段永远不会超过4位数字。

7.10.2.184  -> 7010002184.0
7.11.0.1385 -> 7011001385.0

我希望这能帮助到一些人,因为多重条件句似乎有点过度。