以下是软件版本号:

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

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


当前回答

这实际上取决于版本控制系统背后的逻辑。每个数字代表什么,如何使用。

每个subversion是否是一个用于指定开发阶段的数字? 为0 1代表β 发布候选2个 3为(最终)发布

它是构建版本吗?您是否应用增量更新?

一旦了解了版本控制系统的工作原理,创建算法就变得很容易了。

如果您不允许在每个subversion中使用大于9的数字,则删除所有小数,但第一个小数将允许您进行直接比较。

如果允许在任何一种颠覆版本中使用大于9的数字,有几种方法可以比较它们。最明显的方法是将字符串按小数分割,然后比较每一列。

但是在不知道版本控制系统是如何工作的情况下,当版本1.0.2a发布时,实现像上面这样的过程可能会很麻烦。

其他回答

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

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

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

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

这里找不到我想要的函数。所以我自己写了。这就是我的贡献。我希望有人觉得它有用。

优点:

处理任意长度的版本字符串。'1'或'1.1.1.1.1'。 如果没有指定,则默认为0。仅仅因为字符串更长并不意味着它是一个更大的版本。(“1”应与“1.0”和“1.0.0.0”相同。) 比较数字而不是字符串。('3'<'21'应为真。不是假的。) 不要把时间浪费在无用的比较上。(比较for ==) 你可以选择你自己的比较器。

缺点:

它不处理版本字符串中的字母。(我不知道这是怎么回事?)

我的代码,类似于Jon接受的答案:

function compareVersions(v1, comparator, v2) {
    "use strict";
    var comparator = comparator == '=' ? '==' : comparator;
    if(['==','===','<','<=','>','>=','!=','!=='].indexOf(comparator) == -1) {
        throw new Error('Invalid comparator. ' + comparator);
    }
    var v1parts = v1.split('.'), v2parts = v2.split('.');
    var maxLen = Math.max(v1parts.length, v2parts.length);
    var part1, part2;
    var cmp = 0;
    for(var i = 0; i < maxLen && !cmp; i++) {
        part1 = parseInt(v1parts[i], 10) || 0;
        part2 = parseInt(v2parts[i], 10) || 0;
        if(part1 < part2)
            cmp = 1;
        if(part1 > part2)
            cmp = -1;
    }
    return eval('0' + comparator + cmp);
}

例子:

compareVersions('1.2.0', '==', '1.2'); // true
compareVersions('00001', '==', '1.0.0'); // true
compareVersions('1.2.0', '<=', '1.2'); // true
compareVersions('2.2.0', '<=', '1.2'); // false

功能简单简短:

function isNewerVersion (oldVer, newVer) {
  const oldParts = oldVer.split('.')
  const newParts = newVer.split('.')
  for (var i = 0; i < newParts.length; i++) {
    const a = ~~newParts[i] // parse int
    const b = ~~oldParts[i] // parse int
    if (a > b) return true
    if (a < b) return false
  }
  return false
}

测试:

isNewerVersion('1.0', '2.0') // true
isNewerVersion('1.0', '1.0.1') // true
isNewerVersion('1.0.1', '1.0.10') // true
isNewerVersion('1.0.1', '1.0.1') // false
isNewerVersion('2.0', '1.0') // false
isNewerVersion('2', '1.0') // false
isNewerVersion('2.0.0.0.0.1', '2.1') // true
isNewerVersion('2.0.0.0.0.1', '2.0') // false

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