如何在版本号上使用Javascript数学运算

3
我使用jQuery获取浏览器版本,代码如下:
var x = $.browser.version;

我得到了这样的字符串: 1.9.1.1 现在,如果x大于或等于1.9.1,则我想要进行评估。不幸的是,由于有多个小数点,我不能使用parseFloat()函数,因为它会将1.9.1.1转换为简单的1.9,并且if语句会匹配1.9.0版本(这不是我想要的)。
有人已经想出了一种方法来将版本号(带有多个小数点)转换为可用于评估的数字(或者以其他方式实现我在这里尝试做的事情)吗?
谢谢 -
4个回答

7
你可以使用string.split,然后进行逐位数字比较。
// arr[0] = 1
// arr[1] = 9
// arr[2] = 1
// arr[3] = 1
var arr = ($.browser.version).split('.');

以下内容摘自这篇文章
这是一个函数,可以将您的版本字符串解析并返回一个JSON对象。
function parseVersionString (str) {
    if (typeof(str) != 'string') { return false; }
    var x = str.split('.');

    // parse from string or default to 0 if can't parse 
    var maj = parseInt(x[0]) || 0;
    var min = parseInt(x[1]) || 0;
    var bld = parseInt(x[2]) || 0;
    var rev = parseInt(x[3]) || 0;
    return {
        major: maj,
        minor: min,
        build: bld,
        revision: rev
    }
}

然后你可以使用以下语法。
var version = parseVersionString($.browser.version);
// version.major == 1
// version.minor == 9
// version.build == 1
// version.revision == 1

构建:pat,应该是构建:bld,并且我稍微修改了一下以适应我的使用,但效果很好 - 谢谢! - OneNerd

1

这是另一个版本的versionCmp()

function versionCmp(v1, v2) {
    v1 = String(v1).split('.');
    v2 = String(v2).split('.');

    var diff = 0;
    while((v1.length || v2.length) && !diff)
        diff = (+v1.shift() || 0) - (+v2.shift() || 0);

    return (diff > 0) - (diff < 0);
}

另一种可能是为每个版本号分配一个数值:

function valueOfVersion(ver) {
    ver = String(ver).split('.');

    var value = 0;
    for(var i = ver.length; i--;)
        value += ver[i] / Math.pow(2, i * 8) || 0;

    return value;
}

只有在每个数字小于256(由于硬编码的除数)且具有有限精度(即版本字符串不能任意变长)的情况下,此方法才有效。


优秀。一元加号。未充分利用的移位方法。但为什么是“String”? - Nosredna
String() 用于将值转换为字符串;否则,非字符串参数会抛出错误;有了转换,您可以提供数字参数,如 1.5,并且仍然可以获得某些有意义的结果。 - Christoph
我不确定那是否就是这样。但由于您愿意使用一元加号将字符串转换为数字,您也可能会使用+""将数字转换为字符串。 v1 = (v1+"").split('.'); 我不是说您应该这么做。 - Nosredna
使用 +'' 也可以,但这样很丑:在我看来,显式转换更易读。 - Christoph
我可以对你的一元加号提出同样的论点。 :-) - Nosredna
是的,这就是为什么我通常总是使用显式转换的原因;但由于代码中包含了大量的“有趣的东西”,我认为只要不违反美学价值,采用hackish版本是合适的。 - Christoph

0
你需要将字符串中的每个部分都作为单独的整数处理,因此需要拆分并迭代,并使用 cmp 进行比较:
// perform cmp(a, b)
// -1 = a is smaller
// 0 = equal
// 1 = a is bigger
function versionCmp(a, b) {
  a = a.split(".");
  b = b.split(".");
  for(var i=0; i < a.length; i++) {
    av = parseInt(a[i]);
    bv = parseInt(b[i]);
    if (av < bv) {
      return -1;
    } else if (av > bv) {
      return 1;
    }
  }
  return 0;    
}

console.log(versionCmp("1.1.2.3", "1.2.1.0"));  // should be -1
console.log(versionCmp("1.19.0.1", "1.2.0.4"));  // should be 1
console.log(versionCmp("1.2.3.4", "1.2.3.4"));  // should be 0

如果版本号的数字位数不同,就不能正常工作:您必须检查 i < a.length || i < b.length 并在溢出时将 avbv 设置为 0 - Christoph
是的,我本来打算修改它并进行你所做的打包,但那时候Jon的答案已经被接受了;我觉得没有太大意义。 - Richard Levasseur

-3
你可以移除所有的小数点,然后将其解析为整数。 但请注意,这种解决方案在长期内可能不起作用。

已经考虑过这个问题了--不行,因为版本号可能是2.0(转换成20),但是2.0比1.9.1.1(例如)更大。 - OneNerd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接