以下是软件版本号:

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

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


当前回答

例如,如果我们想检查当前jQuery版本是否小于1.8,如果version是"1.10.1",parseFloat($.ui.version) < 1.8)将会给出错误的结果,因为parseFloat("1.10.1")返回1.1。 字符串比较也会出错,因为"1.8" < "1.10"的结果为false。

所以我们需要一个这样的测试

if(versionCompare($.ui.version, "1.8") < 0){
    alert("please update jQuery");
}

下面的函数可以正确地处理这个问题:

/** Compare two dotted version strings (like '10.2.3').
 * @returns {Integer} 0: v1 == v2, -1: v1 < v2, 1: v1 > v2
 */
function versionCompare(v1, v2) {
    var v1parts = ("" + v1).split("."),
        v2parts = ("" + v2).split("."),
        minLength = Math.min(v1parts.length, v2parts.length),
        p1, p2, i;
    // Compare tuple pair-by-pair. 
    for(i = 0; i < minLength; i++) {
        // Convert to integer if possible, because "8" > "10".
        p1 = parseInt(v1parts[i], 10);
        p2 = parseInt(v2parts[i], 10);
        if (isNaN(p1)){ p1 = v1parts[i]; } 
        if (isNaN(p2)){ p2 = v2parts[i]; } 
        if (p1 == p2) {
            continue;
        }else if (p1 > p2) {
            return 1;
        }else if (p1 < p2) {
            return -1;
        }
        // one operand is NaN
        return NaN;
    }
    // The longer tuple is always considered 'greater'
    if (v1parts.length === v2parts.length) {
        return 0;
    }
    return (v1parts.length < v2parts.length) ? -1 : 1;
}

下面是一些例子:

// compare dotted version strings
console.assert(versionCompare("1.8",      "1.8.1")    <   0);
console.assert(versionCompare("1.8.3",    "1.8.1")    >   0);
console.assert(versionCompare("1.8",      "1.10")     <   0);
console.assert(versionCompare("1.10.1",   "1.10.1")   === 0);
// Longer is considered 'greater'
console.assert(versionCompare("1.10.1.0", "1.10.1")   >   0);
console.assert(versionCompare("1.10.1",   "1.10.1.0") <   0);
// Strings pairs are accepted
console.assert(versionCompare("1.x",      "1.x")      === 0);
// Mixed int/string pairs return NaN
console.assert(isNaN(versionCompare("1.8", "1.x")));
//works with plain numbers
console.assert(versionCompare("4", 3)   >   0);

看到这里的现场示例和测试套件: http://jsfiddle.net/mar10/8KjvP/

其他回答

我根据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
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
    }
}

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

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

如果两个版本相等,函数将返回-1,如果第一个版本是最新版本,则返回0,而1表示第二个版本是最新版本。

let v1 = '12.0.1.0'
let v2 = '12.0.1'

let temp1 = v1.split('.');
let temp2 = v2.split('.');

console.log(compareVersion(temp1, temp2))


function compareVersion(version1, version2) {
    let flag = false;
    var compareResult;
    let maxLength = Math.max(version1.length, version2.length); 
    let minLength = Math.min(version1.length, version2.length);

    for (let i = 0; i < maxLength; ++i ) {
        let result = version1[i] - version2[i];
        if (result > 0) {
            flag = true;
            compareResult = 0;
            break;
        }
        else if (result < 0) {
            flag = true;
            compareResult = 1;
            break;
        }

        if (i === minLength) {
            if (version1.length > version1.length) {
                compareResult = version1[version1.length-1] > 0 ? '0' : '-1'
            }  else  {
                compareResult = version1[version2.length-1] > 0 ? '1' : '-1'
            }
            break;
        }
    }
    if (flag === false) {
        compareResult = -1;
    }
    return compareResult;
}

你可以使用带有选项的String#localeCompare

sensitivity Which differences in the strings should lead to non-zero result values. Possible values are: "base": Only strings that differ in base letters compare as unequal. Examples: a ≠ b, a = á, a = A. "accent": Only strings that differ in base letters or accents and other diacritic marks compare as unequal. Examples: a ≠ b, a ≠ á, a = A. "case": Only strings that differ in base letters or case compare as unequal. Examples: a ≠ b, a = á, a ≠ A. "variant": Strings that differ in base letters, accents and other diacritic marks, or case compare as unequal. Other differences may also be taken into consideration. Examples: a ≠ b, a ≠ á, a ≠ A. The default is "variant" for usage "sort"; it's locale dependent for usage "search". numeric Whether numeric collation should be used, such that "1" < "2" < "10". Possible values are true and false; the default is false. This option can be set through an options property or through a Unicode extension key; if both are provided, the options property takes precedence. Implementations are not required to support this property.

var版本=[" 2.0.1”、“2.0”、“1.0”、“1.0.1”,“2.0.0.1”); 版本。sort((a, b) => a.localeCompare(b, undefined, {numeric: true,灵敏度:'base'})); console.log(版本);