以下是软件版本号:
"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"
这样可以更清楚地看到背后的想法。
但是,我怎样才能把它转换成计算机程序呢?
这适用于由句点分隔的任何长度的数字版本。只有当myVersion为>= minimumVersion时,它才返回true,假设版本1小于1.0,版本1.1小于1.1.0,以此类推。添加额外的条件应该相当简单,比如接受数字(只需转换为字符串)和十六进制,或者使分隔符动态(只需添加一个分隔符参数,然后将“。”替换为参数)
function versionCompare(myVersion, minimumVersion) {
var v1 = myVersion.split("."), v2 = minimumVersion.split("."), minLength;
minLength= Math.min(v1.length, v2.length);
for(i=0; i<minLength; i++) {
if(Number(v1[i]) > Number(v2[i])) {
return true;
}
if(Number(v1[i]) < Number(v2[i])) {
return false;
}
}
return (v1.length >= v2.length);
}
下面是一些测试:
console.log(versionCompare("4.4.0","4.4.1"));
console.log(versionCompare("5.24","5.2"));
console.log(versionCompare("4.1","4.1.2"));
console.log(versionCompare("4.1.2","4.1"));
console.log(versionCompare("4.4.4.4","4.4.4.4.4"));
console.log(versionCompare("4.4.4.4.4.4","4.4.4.4.4"));
console.log(versionCompare("0","1"));
console.log(versionCompare("1","1"));
console.log(versionCompare("","1"));
console.log(versionCompare("10.0.1","10.1"));
这里有一个递归版本
function versionCompare(myVersion, minimumVersion) {
return recursiveCompare(myVersion.split("."),minimumVersion.split("."),Math.min(myVersion.length, minimumVersion.length),0);
}
function recursiveCompare(v1, v2,minLength, index) {
if(Number(v1[index]) < Number(v2[index])) {
return false;
}
if(Number(v1[i]) < Number(v2[i])) {
return true;
}
if(index === minLength) {
return (v1.length >= v2.length);
}
return recursiveCompare(v1,v2,minLength,index+1);
}
下面是一个版本,它对版本字符串进行排序,而不分配任何子字符串或数组。由于它分配的对象更少,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;
}
我必须比较我的扩展版本,但我没有
在这里找到一个可行的解决方案。在比较1.89 > 1.9或1.24.1 == 1.240.1时,几乎所有提议的期权都被打破了
这里,我从仅在最后的记录1.1 == 1.10和1.10.1 > 1.1.1中0下降的事实开始
compare_version = (new_version, old_version) => {
new_version = new_version.split('.');
old_version = old_version.split('.');
for(let i = 0, m = Math.max(new_version.length, old_version.length); i<m; i++){
//compare text
let new_part = (i<m-1?'':'.') + (new_version[i] || 0)
, old_part = (i<m-1?'':'.') + (old_version[i] || 0);
//compare number (I don’t know what better)
//let new_part = +((i<m-1?0:'.') + new_version[i]) || 0
//, old_part = +((i<m-1?0:'.') + old_version[i]) || 0;
//console.log(new_part, old_part);
if(old_part > new_part)return 0; //change to -1 for sort the array
if(new_part > old_part)return 1
}
return 0
};
compare_version('1.0.240.1','1.0.240.1'); //0
compare_version('1.0.24.1','1.0.240.1'); //0
compare_version('1.0.240.89','1.0.240.9'); //0
compare_version('1.0.24.1','1.0.24'); //1
我不是一个大专家,但我构建了简单的代码来比较两个版本,将第一个返回值更改为-1以对版本数组进行排序
['1.0.240', '1.0.24', '1.0.240.9', '1.0.240.89'].sort(compare_version)
//results ["1.0.24", "1.0.240", "1.0.240.89", "1.0.240.9"]
和短版本的比较全字符串
c=e=>e.split('.').map((e,i,a)=>e[i<a.length-1?'padStart':'padEnd'](5)).join('');
//results " 1 0 2409 " > " 1 0 24089 "
c('1.0.240.9')>c('1.0.240.89') //true
如果您有意见或改进,请不要犹豫提出建议。
你可以使用带有选项的String#localeCompare
sensitivity
Which differences in the strings should lead to non-zero result values. Possible values are:
"base": Only strings that differ in base letters compare as unequal. Examples: a ≠ b, a = á, a = A.
"accent": Only strings that differ in base letters or accents and other diacritic marks compare as unequal. Examples: a ≠ b, a ≠ á, a = A.
"case": Only strings that differ in base letters or case compare as unequal. Examples: a ≠ b, a = á, a ≠ A.
"variant": Strings that differ in base letters, accents and other diacritic marks, or case compare as unequal. Other differences may also be taken into consideration. Examples: a ≠ b, a ≠ á, a ≠ A.
The default is "variant" for usage "sort"; it's locale dependent for usage "search".
numeric
Whether numeric collation should be used, such that "1" < "2" < "10". Possible values are true and false; the default is false. This option can be set through an options property or through a Unicode extension key; if both are provided, the options property takes precedence. Implementations are not required to support this property.
var版本=[" 2.0.1”、“2.0”、“1.0”、“1.0.1”,“2.0.0.1”);
版本。sort((a, b) => a.localeCompare(b, undefined, {numeric: true,灵敏度:'base'}));
console.log(版本);