以下是软件版本号:

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

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


当前回答

这里有一个面向对象的有趣方法:

    function versionString(str) {
    var parts = str.split('.');
    this.product = parts.length > 0 ? parts[0] * 1 : 0;
    this.major = parts.length > 1 ? parts[1] * 1 : 0;
    this.minor = parts.length > 2 ? parts[2] * 1 : 0;
    this.build = parts.length > 3 ? parts[3] * 1 : 0;

    this.compareTo = function(vStr){
        vStr = this._isVersionString(vStr) ? vStr : new versionString(vStr);
        return this.compare(this, vStr);
    };

    this.toString = function(){
        return this.product + "." + this.major + "." + this.minor + "." + this.build;
    }

    this.compare = function (str1, str2) {
        var vs1 = this._isVersionString(str1) ? str1 : new versionString(str1);
        var vs2 = this._isVersionString(str2) ? str2 : new versionString(str2);

        if (this._compareNumbers(vs1.product, vs2.product) == 0) {
            if (this._compareNumbers(vs1.major, vs2.major) == 0) {
                if (this._compareNumbers(vs1.minor, vs2.minor) == 0) {
                    return this._compareNumbers(vs1.build, vs2.build);
                } else {
                    return this._compareNumbers(vs1.minor, vs2.minor);
                }
            } else {
                return this._compareNumbers(vs1.major, vs2.major);
            }
        } else {
            return this._compareNumbers(vs1.product, vs2.product);
        }
    };

    this._isVersionString = function (str) {
        return str !== undefined && str.build !== undefined;
    };

    this._compareNumbers = function (n1, n2) {
        if (n1 > n2) {
            return 1;
        } else if (n1 < n2) {
            return -1;
        } else {
            return 0;
        }
    };
}

还有一些测试:

var v1 = new versionString("1.0");
var v2 = new versionString("1.0.1");
var v3 = new versionString("2.0");
var v4 = new versionString("2.0.0.1");
var v5 = new versionString("2.0.1");


alert(v1.compareTo("1.4.2"));
alert(v3.compareTo(v1));
alert(v5.compareTo(v4));
alert(v4.compareTo(v5));
alert(v5.compareTo(v5));

其他回答

这里有一个面向对象的有趣方法:

    function versionString(str) {
    var parts = str.split('.');
    this.product = parts.length > 0 ? parts[0] * 1 : 0;
    this.major = parts.length > 1 ? parts[1] * 1 : 0;
    this.minor = parts.length > 2 ? parts[2] * 1 : 0;
    this.build = parts.length > 3 ? parts[3] * 1 : 0;

    this.compareTo = function(vStr){
        vStr = this._isVersionString(vStr) ? vStr : new versionString(vStr);
        return this.compare(this, vStr);
    };

    this.toString = function(){
        return this.product + "." + this.major + "." + this.minor + "." + this.build;
    }

    this.compare = function (str1, str2) {
        var vs1 = this._isVersionString(str1) ? str1 : new versionString(str1);
        var vs2 = this._isVersionString(str2) ? str2 : new versionString(str2);

        if (this._compareNumbers(vs1.product, vs2.product) == 0) {
            if (this._compareNumbers(vs1.major, vs2.major) == 0) {
                if (this._compareNumbers(vs1.minor, vs2.minor) == 0) {
                    return this._compareNumbers(vs1.build, vs2.build);
                } else {
                    return this._compareNumbers(vs1.minor, vs2.minor);
                }
            } else {
                return this._compareNumbers(vs1.major, vs2.major);
            }
        } else {
            return this._compareNumbers(vs1.product, vs2.product);
        }
    };

    this._isVersionString = function (str) {
        return str !== undefined && str.build !== undefined;
    };

    this._compareNumbers = function (n1, n2) {
        if (n1 > n2) {
            return 1;
        } else if (n1 < n2) {
            return -1;
        } else {
            return 0;
        }
    };
}

还有一些测试:

var v1 = new versionString("1.0");
var v2 = new versionString("1.0.1");
var v3 = new versionString("2.0");
var v4 = new versionString("2.0.0.1");
var v5 = new versionString("2.0.1");


alert(v1.compareTo("1.4.2"));
alert(v3.compareTo(v1));
alert(v5.compareTo(v4));
alert(v4.compareTo(v5));
alert(v5.compareTo(v5));

你不能把它们转换成数字,然后按大小排序吗?在长度< 4的数的1后面加上0

在主机上玩:

$(["1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1", "3.0"]).each(function(i,e) {
    var n =   e.replace(/\./g,"");
    while(n.length < 4) n+="0" ; 
    num.push(  +n  )
});

版本越大,数字越大。 编辑:可能需要调整,以考虑更大的版本系列

我认为这是一个值得分享的实现,因为它简短,简单,但功能强大。请注意,它只使用数字比较。通常它会检查version2是否比version1晚,如果是,则返回true。假设您有version1: 1.1.1和version2: 1.1.2。它遍历两个版本的每个部分,将它们的部分相加如下:对于版本1(1 + 0.1)然后(1.1 + 0.01),对于版本2(1 + 0.1)然后(1.1 + 0.02)。

function compareVersions(version1, version2) {

    version1 = version1.split('.');
    version2 = version2.split('.');

    var maxSubVersionLength = String(Math.max.apply(undefined, version1.concat(version2))).length;

    var reduce = function(prev, current, index) {

        return parseFloat(prev) + parseFloat('0.' + Array(index + (maxSubVersionLength - String(current).length)).join('0') + current);
    };

    return version1.reduce(reduce) < version2.reduce(reduce);
}

如果你想从版本列表中找到最新的版本,那么这可能是有用的:

function findLatestVersion(versions) {

    if (!(versions instanceof Array)) {
        versions = Array.prototype.slice.apply(arguments, [0]);
    }

    versions = versions.map(function(version) { return version.split('.'); });

    var maxSubVersionLength = String(Math.max.apply(undefined, Array.prototype.concat.apply([], versions))).length;

    var reduce = function(prev, current, index) {

        return parseFloat(prev) + parseFloat('0.' + Array(index + (maxSubVersionLength - String(current).length)).join('0') + current);
    };

    var sums = [];

    for (var i = 0; i < versions.length; i++) {
        sums.push(parseFloat(versions[i].reduce(reduce)));
    }

    return versions[sums.indexOf(Math.max.apply(undefined, sums))].join('.');
}

console.log(findLatestVersion('0.1000000.1', '2.0.0.10', '1.6.10', '1.4.3', '2', '2.0.0.1')); // 2.0.0.10
console.log(findLatestVersion(['0.1000000.1', '2.0.0.10', '1.6.10', '1.4.3', '2', '2.0.0.1'])); // 2.0.0.10
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
    }
}

我不喜欢任何一个解决方案,所以我根据自己的编码偏好重新编写了它。请注意,最后四个检查结果与接受的答案略有不同。对我有用。

function v_check(version_a, version_b) {
    // compares version_a as it relates to version_b
    // a = b => "same"
    // a > b => "larger"
    // a < b => "smaller"
    // NaN   => "invalid"

    const arr_a = version_a.split('.');
    const arr_b = version_b.split('.');

    let result = "same"; // initialize to same // loop tries to disprove

    // loop through a and check each number against the same position in b
    for (let i = 0; i < arr_a.length; i++) {
        let a = arr_a[i];
        let b = arr_b[i];

        // same up to this point so if a is not there, a is smaller
        if (typeof a === 'undefined') {
            result = "smaller";
            break;

        // same up to this point so if b is not there, a is larger
        } else if (typeof b === 'undefined') {
            result = "larger";
            break;

        // otherwise, compare the two numbers
        } else {

            // non-positive numbers are invalid
            if (a >= 0 && b >= 0) {

                if (a < b) {
                    result = "smaller";
                    break;
                }
                else if (a > b) {
                    result = "larger";
                    break;
                }

            } else {
                result = "invalid";
                break;
            }
        }
    }

    // account for the case where the loop ended but there was still a position in b to evaluate
    if (result == "same" && arr_b.length > arr_a.length) result = "smaller";

    return result;
}


console.log(v_check("1.7.1", "1.7.10"));  // smaller
console.log(v_check("1.6.1", "1.7.10"));  // smaller
console.log(v_check("1.6.20", "1.7.10")); // smaller
console.log(v_check("1.7.1", "1.7.10"));  // smaller
console.log(v_check("1.7", "1.7.0"));     // smaller
console.log(v_check("1.7", "1.8.0"));     // smaller

console.log(v_check("1.7.10", "1.7.1"));  // larger
console.log(v_check("1.7.10", "1.6.1"));  // larger
console.log(v_check("1.7.10", "1.6.20")); // larger
console.log(v_check("1.7.0", "1.7"));     // larger
console.log(v_check("1.8.0", "1.7"));     // larger

console.log(v_check("1.7.10", "1.7.10")); // same
console.log(v_check("1.7", "1.7"));       // same

console.log(v_check("1.7", "1..7")); // larger
console.log(v_check("1.7", "Bad"));  // invalid
console.log(v_check("1..7", "1.7")); // smaller
console.log(v_check("Bad", "1.7"));  // invalid