以下是软件版本号:

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

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


当前回答

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

其他回答

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

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

你可以遍历每个以句点分隔的字符并将其转换为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?
}

你可以使用JavaScript的localeCompare方法:

a.localeCompare(b, undefined, {numeric: true})

这里有一个例子:

"1.1".localeCompare("2.1.1", undefined, {numeric: true}) => -1

"1.0.0".localeCompare("1.0", undefined, {numeric: true}) =>

"1.0.0".localeCompare("1.0.0", undefined, {numeric: true}) => 0

我写了一个排序版本的节点模块,你可以在这里找到它:version-sort

特点:

序列“1.0.1.5.53.54654.114.1.154.45”不受限制 不限制序列长度:'1.1546515465451654654654654138754431574364321353734'工作 可以根据版本对对象进行排序(参见README) 阶段(如alpha, beta, rc1, rc2)

如果您需要其他功能,请不要犹豫,打开一个问题。

replace()函数只替换字符串中的第一个出现项。我们来替换。与,。然后全部删除。然后做,to。再次将其解析为float。

for(i=0; i<versions.length; i++) {
    v = versions[i].replace('.', ',');
    v = v.replace(/\./g, '');
    versions[i] = parseFloat(v.replace(',', '.'));
}

最后,排序:

versions.sort();