以下是软件版本号:

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

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


当前回答

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

其他回答

现在我们可以使用Intl了。Collator API现在创建数值比较器。浏览器支持是相当不错的,但在撰写本文时,Node.js还不支持。

const semverCompare = new Intl。Collator("en", {numeric: true}).compare; const版本=[1.0.1,“1.10.2”,“1.1.1”,‘1.10.1’,‘1.5.10’,‘2.10.0’,‘2.0.1’); console.log (versions.sort (semverCompare)) const example2 =(“1.0”,“1.0.1”,“2.0”,“2.0.0.1”,“2.0.1”); console.log (example2.sort (semverCompare))

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

摘自http://java.com/js/deployJava.js:

    // return true if 'installed' (considered as a JRE version string) is
    // greater than or equal to 'required' (again, a JRE version string).
    compareVersions: function (installed, required) {

        var a = installed.split('.');
        var b = required.split('.');

        for (var i = 0; i < a.length; ++i) {
            a[i] = Number(a[i]);
        }
        for (var i = 0; i < b.length; ++i) {
            b[i] = Number(b[i]);
        }
        if (a.length == 2) {
            a[2] = 0;
        }

        if (a[0] > b[0]) return true;
        if (a[0] < b[0]) return false;

        if (a[1] > b[1]) return true;
        if (a[1] < b[1]) return false;

        if (a[2] > b[2]) return true;
        if (a[2] < b[2]) return false;

        return true;
    }

下面是另一个简短的版本,适用于任何数量的子版本,填充零和偶数字母(1.0.0b3)

const compareVer = ((prep, repl) =>
{
  prep = t => ("" + t)
      //treat non-numerical characters as lower version
      //replacing them with a negative number based on charcode of first character
    .replace(/[^0-9\.]+/g, c => "." + (c.replace(/[\W_]+/, "").toLowerCase().charCodeAt(0) - 65536) + ".")
      //remove trailing "." and "0" if followed by non-numerical characters (1.0.0b);
    .replace(/(?:\.0+)*(\.-[0-9]+)(\.[0-9]+)?\.*$/g, "$1$2")
    .split('.');

  return (a, b, c, i, r) =>
  {
    a = prep(a);
    b = prep(b);
    for (i = 0, r = 0, c = Math.max(a.length, b.length); !r && i++ < c;)
    {
      r = -1 * ((a[i] = ~~a[i]) < (b[i] = ~~b[i])) + (a[i] > b[i]);
    }
    return r;
  }
})();

函数返回:

如果a = b则为0

1如果a > b

-1如果a < b

1.0         = 1.0.0.0.0.0
1.0         < 1.0.1
1.0b1       < 1.0
1.0b        = 1.0b
1.1         > 1.0.1b
1.1alpha    < 1.1beta
1.1rc1      > 1.1beta
1.1rc1      < 1.1rc2
1.1.0a1     < 1.1a2
1.1.0a10    > 1.1.0a1
1.1.0alpha  = 1.1a
1.1.0alpha2 < 1.1b1
1.0001      > 1.00000.1.0.0.0.01

/*use strict*/ const compareVer = ((prep, repl) => { prep = t => ("" + t) //treat non-numerical characters as lower version //replacing them with a negative number based on charcode of first character .replace(/[^0-9\.]+/g, c => "." + (c.replace(/[\W_]+/, "").toLowerCase().charCodeAt(0) - 65536) + ".") //remove trailing "." and "0" if followed by non-numerical characters (1.0.0b); .replace(/(?:\.0+)*(\.-[0-9]+)(\.[0-9]+)?\.*$/g, "$1$2") .split('.'); return (a, b, c, i, r) => { a = prep(a); b = prep(b); for (i = 0, r = 0, c = Math.max(a.length, b.length); !r && i++ < c;) { r = -1 * ((a[i] = ~~a[i]) < (b[i] = ~~b[i])) + (a[i] > b[i]); } return r; } })(); //examples let list = [ ["1.0", "1.0.0.0.0.0"], ["1.0", "1.0.1"], ["1.0b1", "1.0"], ["1.0b", "1.0b"], ["1.1", "1.0.1b"], ["1.1alpha", "1.1beta"], ["1.1rc1", "1.1beta"], ["1.1rc1", "1.1rc2"], ["1.1.0a1", "1.1a2"], ["1.1.0a10", "1.1.0a1"], ["1.1.0alpha", "1.1a"], ["1.1.0alpha2", "1.1b1"], ["1.0001", "1.00000.1.0.0.0.01"] ] for(let i = 0; i < list.length; i++) { console.log( list[i][0] + " " + "<=>"[compareVer(list[i][0], list[i][1]) + 1] + " " + list[i][1] ); }

https://jsfiddle.net/vanowm/p7uvtbor/

这是另一种递归算法。

这段代码只使用了Array。shift和递归,这意味着它可以在Internet Explorer 6+中运行。如果你有任何疑问,你可以访问我的GitHub页面。

(function(root, factory) {
  if (typeof exports === 'object') {
    return module.exports = factory();
  } else if (typeof define === 'function' && define.amd) {
    return define(factory);
  } else {
    return root.compareVer = factory();
  }
})(this, function() {
  'use strict';
  var _compareVer;
  _compareVer = function(newVer, oldVer) {
    var VER_RE, compareNum, isTrue, maxLen, newArr, newLen, newMatch, oldArr, oldLen, oldMatch, zerofill;
    VER_RE = /(\d+\.){1,9}\d+/;
    if (arguments.length !== 2) {
      return -100;
    }
    if (typeof newVer !== 'string') {
      return -2;
    }
    if (typeof oldVer !== 'string') {
      return -3;
    }
    newMatch = newVer.match(VER_RE);
    if (!newMatch || newMatch[0] !== newVer) {
      return -4;
    }
    oldMatch = oldVer.match(VER_RE);
    if (!oldMatch || oldMatch[0] !== oldVer) {
      return -5;
    }
    newVer = newVer.replace(/^0/, '');
    oldVer = oldVer.replace(/^0/, '');
    if (newVer === oldVer) {
      return 0;
    } else {
      newArr = newVer.split('.');
      oldArr = oldVer.split('.');
      newLen = newArr.length;
      oldLen = oldArr.length;
      maxLen = Math.max(newLen, oldLen);
      zerofill = function() {
        newArr.length < maxLen && newArr.push('0');
        oldArr.length < maxLen && oldArr.push('0');
        return newArr.length !== oldArr.length && zerofill();
      };
      newLen !== oldLen && zerofill();
      if (newArr.toString() === oldArr.toString()) {
        if (newLen > oldLen) {
          return 1;
        } else {
          return -1;
        }
      } else {
        isTrue = -1;
        compareNum = function() {
          var _new, _old;
          _new = ~~newArr.shift();
          _old = ~~oldArr.shift();
          _new > _old && (isTrue = 1);
          return _new === _old && newArr.length > 0 && compareNum();
        };
        compareNum();
        return isTrue;
      }
    }
  };
  return _compareVer;
});

好吧,我希望这段代码能帮助到一些人。

下面是测试。

console.log(compareVer("0.0.2","0.0.1"));//1
console.log(compareVer("0.0.10","0.0.1")); //1
console.log(compareVer("0.0.10","0.0.2")); //1
console.log(compareVer("0.9.0","0.9")); //1
console.log(compareVer("0.10.0","0.9.0")); //1
console.log(compareVer("1.7", "1.07")); //1
console.log(compareVer("1.0.07", "1.0.007")); //1

console.log(compareVer("0.3","0.3")); //0
console.log(compareVer("0.0.3","0.0.3")); //0
console.log(compareVer("0.0.3.0","0.0.3.0")); //0
console.log(compareVer("00.3","0.3")); //0
console.log(compareVer("00.3","00.3")); //0
console.log(compareVer("01.0.3","1.0.3")); //0
console.log(compareVer("1.0.3","01.0.3")); //0

console.log(compareVer("0.2.0","1.0.0")); //-1
console.log(compareVer('0.0.2.2.0',"0.0.2.3")); //-1
console.log(compareVer('0.0.2.0',"0.0.2")); //-1
console.log(compareVer('0.0.2',"0.0.2.0")); //-1
console.log(compareVer("1.07", "1.7")); //-1
console.log(compareVer("1.0.007", "1.0.07")); //-1

console.log(compareVer()); //-100
console.log(compareVer("0.0.2")); //-100
console.log(compareVer("0.0.2","0.0.2","0.0.2")); //-100
console.log(compareVer(1212,"0.0.2")); //-2
console.log(compareVer("0.0.2",1212)); //-3
console.log(compareVer('1.abc.2',"1.0.2")); //-4
console.log(compareVer('1.0.2',"1.abc.2")); //-5