以下是软件版本号:
"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"
这样可以更清楚地看到背后的想法。
但是,我怎样才能把它转换成计算机程序呢?
我根据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
我不喜欢任何一个解决方案,所以我根据自己的编码偏好重新编写了它。请注意,最后四个检查结果与接受的答案略有不同。对我有用。
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
这个非常小,但非常快的比较函数接受每个段的任何长度和任何数字大小的版本号。
返回值:
-如果a < b,则数字< 0
-如果是> b,则为> 0
如果a = b - 0
所以你可以使用它作为array。sort()的比较函数;
编辑:修正了版本剥离尾随零识别“1”和“1.0.0”相等的错误
function cmpVersions (a, b) {
var i, diff;
var regExStrip0 = /(\.0+)+$/;
var segmentsA = a.replace(regExStrip0, '').split('.');
var segmentsB = b.replace(regExStrip0, '').split('.');
var l = Math.min(segmentsA.length, segmentsB.length);
for (i = 0; i < l; i++) {
diff = parseInt(segmentsA[i], 10) - parseInt(segmentsB[i], 10);
if (diff) {
return diff;
}
}
return segmentsA.length - segmentsB.length;
}
// TEST
console.log(
['2.5.10.4159',
'1.0.0',
'0.5',
'0.4.1',
'1',
'1.1',
'0.0.0',
'2.5.0',
'2',
'0.0',
'2.5.10',
'10.5',
'1.25.4',
'1.2.15'].sort(cmpVersions));
// Result:
// ["0.0.0", "0.0", "0.4.1", "0.5", "1.0.0", "1", "1.1", "1.2.15", "1.25.4", "2", "2.5.0", "2.5.10", "2.5.10.4159", "10.5"]
功能简单简短:
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