以下是软件版本号:
"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"
这样可以更清楚地看到背后的想法。
但是,我怎样才能把它转换成计算机程序呢?
下面是一个版本,它对版本字符串进行排序,而不分配任何子字符串或数组。由于它分配的对象更少,GC要做的工作也就更少。
有一对分配(允许重用getVersionPart方法),但是如果您对性能非常敏感,您可以扩展它以完全避免分配。
const compareVersionStrings : (a: string, b: string) => number = (a, b) =>
{
var ia = {s:a,i:0}, ib = {s:b,i:0};
while (true)
{
var na = getVersionPart(ia), nb = getVersionPart(ib);
if (na === null && nb === null)
return 0;
if (na === null)
return -1;
if (nb === null)
return 1;
if (na > nb)
return 1;
if (na < nb)
return -1;
}
};
const zeroCharCode = '0'.charCodeAt(0);
const getVersionPart = (a : {s:string, i:number}) =>
{
if (a.i >= a.s.length)
return null;
var n = 0;
while (a.i < a.s.length)
{
if (a.s[a.i] === '.')
{
a.i++;
break;
}
n *= 10;
n += a.s.charCodeAt(a.i) - zeroCharCode;
a.i++;
}
return n;
}
我也遇到过类似的问题,而且我已经为它创建了一个解决方案。你可以试一试。
如果等于则返回0,如果版本号大于则返回1,如果版本号小于则返回-1
function compareVersion(currentVersion, minVersion) {
let current = currentVersion.replace(/\./g," .").split(' ').map(x=>parseFloat(x,10))
let min = minVersion.replace(/\./g," .").split(' ').map(x=>parseFloat(x,10))
for(let i = 0; i < Math.max(current.length, min.length); i++) {
if((current[i] || 0) < (min[i] || 0)) {
return -1
} else if ((current[i] || 0) > (min[i] || 0)) {
return 1
}
}
return 0
}
console.log(compareVersion("81.0.1212.121","80.4.1121.121"));
console.log(compareVersion("81.0.1212.121","80.4.9921.121"));
console.log(compareVersion("80.0.1212.121","80.4.9921.121"));
console.log(compareVersion("4.4.0","4.4.1"));
console.log(compareVersion("5.24","5.2"));
console.log(compareVersion("4.1","4.1.2"));
console.log(compareVersion("4.1.2","4.1"));
console.log(compareVersion("4.4.4.4","4.4.4.4.4"));
console.log(compareVersion("4.4.4.4.4.4","4.4.4.4.4"));
console.log(compareVersion("0","1"));
console.log(compareVersion("1","1"));
console.log(compareVersion("1","1.0.00000.0000"));
console.log(compareVersion("","1"));
console.log(compareVersion("10.0.1","10.1"));
// Return 1 if a > b
// Return -1 if a < b
// Return 0 if a == b
function compare(a, b) {
if (a === b) {
return 0;
}
var a_components = a.split(".");
var b_components = b.split(".");
var len = Math.min(a_components.length, b_components.length);
// loop while the components are equal
for (var i = 0; i < len; i++) {
// A bigger than B
if (parseInt(a_components[i]) > parseInt(b_components[i])) {
return 1;
}
// B bigger than A
if (parseInt(a_components[i]) < parseInt(b_components[i])) {
return -1;
}
}
// If one's a prefix of the other, the longer one is greater.
if (a_components.length > b_components.length) {
return 1;
}
if (a_components.length < b_components.length) {
return -1;
}
// Otherwise they are the same.
return 0;
}
console.log(compare("1", "2"));
console.log(compare("2", "1"));
console.log(compare("1.0", "1.0"));
console.log(compare("2.0", "1.0"));
console.log(compare("1.0", "2.0"));
console.log(compare("1.0.1", "1.0"));
我也遇到了版本比较的问题,但是版本可能包含任何内容(例如:不是点的分隔符,像rc1, rc2…)
我使用了这个方法,它基本上将版本字符串分为数字和非数字,并尝试根据类型进行比较。
function versionCompare(a,b) {
av = a.match(/([0-9]+|[^0-9]+)/g)
bv = b.match(/([0-9]+|[^0-9]+)/g)
for (;;) {
ia = av.shift();
ib = bv.shift();
if ( (typeof ia === 'undefined') && (typeof ib === 'undefined') ) { return 0; }
if (typeof ia === 'undefined') { ia = '' }
if (typeof ib === 'undefined') { ib = '' }
ian = parseInt(ia);
ibn = parseInt(ib);
if ( isNaN(ian) || isNaN(ibn) ) {
// non-numeric comparison
if (ia < ib) { return -1;}
if (ia > ib) { return 1;}
} else {
if (ian < ibn) { return -1;}
if (ian > ibn) { return 1;}
}
}
}
对于某些情况,这里有一些假设,例如:"1.01" === "1.1",或"1.8" < "1.71"。它无法管理“1.0.0-rc”。1" < "1.0.0",由语义版本2.0.0指定