如何使用 JavaScript 比较软件版本号? (只有数字)

新手上路,请多包涵

这是软件版本号:

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

这更清楚地看到背后的想法是什么……但是,我怎样才能将它转换成计算机程序呢?

原文由 Tattat 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 590
2 个回答

进行这种比较的基本思想是使用 Array.split 从输入字符串中获取零件数组,然后比较两个数组中的零件对;如果部分不相等,我们知道哪个版本更小。

需要记住一些重要的细节:

  1. 应该如何比较每一对中的零件?这个问题想要比较数字,但是如果我们有不是由数字组成的版本字符串(例如“1.0a”)怎么办?
  2. 如果一个版本字符串的部分多于另一个,会发生什么情况?很可能“1.0”应该被认为小于“1.0.1”,但是“1.0.0”呢?

这是您可以直接使用的实现代码( 带文档的要点):

 function versionCompare(v1, v2, options) {
    var lexicographical = options && options.lexicographical,
        zeroExtend = options && options.zeroExtend,
        v1parts = v1.split('.'),
        v2parts = v2.split('.');

    function isValidPart(x) {
        return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
    }

    if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
        return NaN;
    }

    if (zeroExtend) {
        while (v1parts.length < v2parts.length) v1parts.push("0");
        while (v2parts.length < v1parts.length) v2parts.push("0");
    }

    if (!lexicographical) {
        v1parts = v1parts.map(Number);
        v2parts = v2parts.map(Number);
    }

    for (var i = 0; i < v1parts.length; ++i) {
        if (v2parts.length == i) {
            return 1;
        }

        if (v1parts[i] == v2parts[i]) {
            continue;
        }
        else if (v1parts[i] > v2parts[i]) {
            return 1;
        }
        else {
            return -1;
        }
    }

    if (v1parts.length != v2parts.length) {
        return -1;
    }

    return 0;
}

这个版本比较 自然,不接受字符后缀,认为“1.7”小于“1.7.0”。可以将比较模式更改为字典顺序,并且可以使用可选的第三个参数自动对较短版本的字符串进行零填充。

这里有一个运行“单元测试”的 JSFiddle ;它是 ripper234 作品 的略微扩展版本(谢谢)。

重要说明: 此代码使用 Array.mapArray.every ,这意味着它不会在早于 9 的 IE 版本中运行。如果你需要支持这些,你必须为缺少方法。

原文由 Jon 发布,翻译遵循 CC BY-SA 3.0 许可协议

服务器

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

原文由 Mohammed Akdim 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏