如何使用js比较软件版本号? (唯一号码)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用js比较软件版本号? (唯一号码)相关的知识,希望对你有一定的参考价值。
这是软件版本号:
"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"
这更清楚地看到背后的想法是什么......但是,如何将其转换为计算机程序?有没有人知道如何排序这个?谢谢。
进行这种比较的基本思想是使用Array.split
从输入字符串中获取部件数组,然后比较两个数组中的部件对;如果部件不相等,我们知道哪个版本更小。
需要记住的一些重要细节:
- 如何比较每对中的部件?问题想要在数字上进行比较,但是如果我们的版本字符串不仅仅由数字组成(例如“1.0a”)怎么办?
- 如果一个版本字符串的部分多于另一个版本,会发生什么?最有可能“1.0”应该被认为小于“1.0.1”,但是“1.0.0”呢?
这是您可以直接使用的实现的代码(gist with documentation):
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;
}
此版本比较部分naturally,不接受字符后缀并认为“1.7”小于“1.7.0”。比较模式可以更改为词典编纂,较短版本的字符串可以使用可选的第三个参数自动进行零填充。
有一个JSFiddle运行“单元测试”here;它是ripper234's work的略微扩展版本(谢谢)。
重要说明:此代码使用Array.map
和Array.every
,这意味着它不会在早于9的IE版本中运行。如果需要支持那些,则必须为缺少的方法提供polyfill。
这是一个适合与Array.sort一起使用的coffeescript实现,其灵感来自其他答案:
# Returns > 0 if v1 > v2 and < 0 if v1 < v2 and 0 if v1 == v2
compareVersions = (v1, v2) ->
v1Parts = v1.split('.')
v2Parts = v2.split('.')
minLength = Math.min(v1Parts.length, v2Parts.length)
if minLength > 0
for idx in [0..minLength - 1]
diff = Number(v1Parts[idx]) - Number(v2Parts[idx])
return diff unless diff is 0
return v1Parts.length - v2Parts.length
// Returns true if v1 is bigger than v2, and false if otherwise.
function isNewerThan(v1, v2) {
v1=v1.split('.');
v2=v2.split('.');
for(var i = 0; i<Math.max(v1.length,v2.length); i++){
if(v1[i] == undefined) return false; // If there is no digit, v2 is automatically bigger
if(v2[i] == undefined) return true; // if there is no digit, v1 is automatically bigger
if(v1[i] > v2[i]) return true;
if(v1[i] < v2[i]) return false;
}
return false; // Returns false if they are equal
}
简单功能:
function isNewerVersion (oldVer, newVer) {
const oldParts = oldVer.split('.')
const newParts = newVer.split('.')
for (var i = 0; i < newParts.length; i++) {
const a = parseInt(newParts[i]) || 0
const b = parseInt(oldParts[i]) || 0
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
replace()
函数仅替换字符串中的第一个出现。所以,让我们用.
替换,
。然后删除所有.
并再次使,
到.
并解析它浮动。
for(i=0; i<versions.length; i++) {
v = versions[i].replace('.', ',');
v = v.replace(/./g, '');
versions[i] = parseFloat(v.replace(',', '.'));
}
最后,排序:
versions.sort();
看看这个blog post。此功能适用于数字版本号。
function compVersions(strV1, strV2) {
var nRes = 0
, parts1 = strV1.split('.')
, parts2 = strV2.split('.')
, nLen = Math.max(parts1.length, parts2.length);
for (var i = 0; i < nLen; i++) {
var nP1 = (i < parts1.length) ? parseInt(parts1[i], 10) : 0
, nP2 = (i < parts2.length) ? parseInt(parts2[i], 10) : 0;
if (isNaN(nP1)) { nP1 = 0; }
if (isNaN(nP2)) { nP2 = 0; }
if (nP1 != nP2) {
nRes = (nP1 > nP2) ? 1 : -1;
break;
}
}
return nRes;
};
compVersions('10', '10.0'); // 0
compVersions('10.1', '10.01.0'); // 0
compVersions('10.0.1', '10.0'); // 1
compVersions('10.0.1', '10.1'); // -1
例如,如果我们要检查当前jQuery版本是否小于1.8,那么如果版本为“1.10.1”,则parseFloat($.ui.version) < 1.8 )
将给出错误的结果,因为parseFloat(“1.10.1”)返回1.1
。字符串比较也会出错,因为"1.8" < "1.10"
评估为false
。
所以我们需要这样的测试
if(versionCompare($.ui.version, "1.8") < 0){
alert("please update jQuery");
}
以下函数正确处理此问题:
/** Compare two dotted version strings (like '10.2.3').
* @returns {Integer} 0: v1 == v2, -1: v1 < v2, 1: v1 > v2
*/
function versionCompare(v1, v2) {
var v1parts = ("" + v1).split("."),
v2parts = ("" + v2).split("."),
minLength = Math.min(v1parts.length, v2parts.length),
p1, p2, i;
// Compare tuple pair-by-pair.
for(i = 0; i < minLength; i++) {
// Convert to integer if possible, because "8" > "10".
p1 = parseInt(v1parts[i], 10);
p2 = parseInt(v2parts[i], 10);
if (isNaN(p1)){ p1 = v1parts[i]; }
if (isNaN(p2)){ p2 = v2parts[i]; }
if (p1 == p2) {
continue;
}else if (p1 > p2) {
return 1;
}else if (p1 < p2) {
return -1;
}
// one operand is NaN
return NaN;
}
// The longer tuple is always considered 'greater'
if (v1parts.length === v2parts.length) {
return 0;
}
return (v1parts.length < v2parts.length) ? -1 : 1;
}
这里有些例子:
// compare dotted version strings
console.assert(versionCompare("1.8", "1.8.1") < 0);
console.assert(versionCompare("1.8.3", "1.8.1") > 0);
console.assert(versionCompare("1.8", "1.10") < 0);
console.assert(versionCompare("1.10.1", "1.10.1") === 0);
// Longer is considered 'greater'
console.assert(versionCompare("1.10.1.0", "1.10.1") > 0);
console.assert(versionCompare("1.10.1", "1.10.1.0") < 0);
// Strings pairs are accepted
console.assert(versionCompare("1.x", "1.x") === 0);
// Mixed int/string pairs return NaN
console.assert(isNaN(versionCompare("1.8", "1.x")));
//works with plain numbers
console.assert(versionCompare("4", 3) > 0);
请看这里的实时样本和
以上是关于如何使用js比较软件版本号? (唯一号码)的主要内容,如果未能解决你的问题,请参考以下文章
VIN码识别/车架号识别/车辆唯一编码识别/车辆信息识别提取