以下是软件版本号:

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

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


当前回答

我也遇到了版本比较的问题,但是版本可能包含任何内容(例如:不是点的分隔符,像rc1, rc2…)

我使用了这个方法,它基本上将版本字符串分为数字和非数字,并尝试根据类型进行比较。

function versionCompare(a,b) {
  av = a.match(/([0-9]+|[^0-9]+)/g)
  bv = b.match(/([0-9]+|[^0-9]+)/g)
  for (;;) {
    ia = av.shift();
    ib = bv.shift();
    if ( (typeof ia === 'undefined') && (typeof ib === 'undefined') ) { return 0; }
    if (typeof ia === 'undefined') { ia = '' }
    if (typeof ib === 'undefined') { ib = '' }

    ian = parseInt(ia);
    ibn = parseInt(ib);
    if ( isNaN(ian) || isNaN(ibn) ) {
      // non-numeric comparison
      if (ia < ib) { return -1;}
      if (ia > ib) { return 1;}
    } else {
      if (ian < ibn) { return -1;}
      if (ian > ibn) { return 1;}
    }
  }
}

对于某些情况,这里有一些假设,例如:"1.01" === "1.1",或"1.8" < "1.71"。它无法管理“1.0.0-rc”。1" < "1.0.0",由语义版本2.0.0指定

其他回答

我找到了最简单的方法来比较它们,但我不确定这是否是你想要的。

当我在控制台中运行下面的代码时,它是有意义的,并且使用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"]

这是一个巧妙的技巧。如果您正在处理数值,在特定的值范围内,您可以为版本对象的每个级别分配一个值。例如,“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);

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

返回值: -如果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"]

function compare(versionA: string | undefined, versionB: string | undefined, operator: string = '>') {
    if (versionA === undefined || versionB === undefined) {
        return false
    }
    const listA = versionA.split('.')
    const listB = versionB.split('.')
    let a = []
    let b = []
    for (let i = 0; i < listA.length; i++) {
        a.push(parseInt(listA[i].replace(/\D/g, ''), 10))
        b.push(parseInt(listB[i].replace(/\D/g, ''), 10))
    }

    for (let i = 0; i < listA.length; i++) {
        switch (operator) {
            case '>':
            case '>=':
                if (a[i] === b[i]) {
                    continue
                }
                if (a[i] > b[i]) {
                    return true
                }
                if (a[i] < b[i]) {
                    return false
                }
                break
            case '<':
            case '<=':
                if (a[i] === b[i]) {
                    continue
                }
                if (a[i] > b[i]) {
                    return false
                }
                if (a[i] < b[i]) {
                    return true
                }
                break
            case '=':
               if (a[i] > b[i]) {
                   return false
               }
               if (a[i] < b[i]) {
                   return false
               }
               break
        }
    }
    switch (operator) {
        case '>':
            return false
        case '<':
            return false
        case '=':
        case '>=':
        case '<=':
            return true
    }
}

semver

npm使用的语义版本解析器。

$ npm install semver
var semver = require('semver');

semver.diff('3.4.5', '4.3.7') //'major'
semver.diff('3.4.5', '3.3.7') //'minor'
semver.gte('3.4.8', '3.4.7') //true
semver.ltr('3.4.8', '3.4.7') //false

semver.valid('1.2.3') // '1.2.3'
semver.valid('a.b.c') // null
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true

var versions = [ '1.2.3', '3.4.5', '1.0.2' ]
var max = versions.sort(semver.rcompare)[0]
var min = versions.sort(semver.compare)[0]
var max = semver.maxSatisfying(versions, '*')

语义版本控制链接:https://www.npmjs.com/package/semver#prerelease-identifiers