Javascript 如何比较任意版本号?
有人有代码来比较JavaScript中的两个版本号吗?我只需要简单的版本比较(例如,Javascript 如何比较任意版本号?,javascript,comparison,Javascript,Comparison,有人有代码来比较JavaScript中的两个版本号吗?我只需要简单的版本比较(例如,“1.0”与“1.5.6”),它应该可以处理数字或字符串。它可以忽略后面的beta标识符,如“1.5.6b4”,但也可以期望字符串格式良好。该函数应该像普通cmp函数一样返回有符号整数 function cmpVersion(a, b) return less than one if a < b return 0 if a == b return greater than one if a &g
“1.0”
与“1.5.6”
),它应该可以处理数字或字符串。它可以忽略后面的beta标识符,如“1.5.6b4”
,但也可以期望字符串格式良好。该函数应该像普通cmp函数一样返回有符号整数
function cmpVersion(a, b)
return less than one if a < b
return 0 if a == b
return greater than one if a > b
函数cmpVersion(a,b)
如果ab,则返回大于1的值
我有一个答案,但我会选择一个更好或更优雅的解决方案
(我用它来比较
jQuery.browser.version
数字,但答案会更广泛地适用)如果您不关心.5.6,请使用
既然你说你关心次要版本:
function cmpVersion(v1, v2) {
if(v1===v2) return 0;
var a1 = v1.toString().split(".");
var a2 = v2.toString().split(".");
for( var i = 0; i < a1.length && i < a2.length; i++ ) {
var diff = parseInt(a1[i],10) - parseInt(a2[i],10);
if( diff>0 ) {
return 1;
}
else if( diff<0 ) {
return -1;
}
}
diff = a1.length - a2.length;
return (diff>0) ? 1 : (diff<0) ? -1 : 0;
}
console.log( cmpVersion( "1.0", "1.56") );
console.log( cmpVersion( "1.56", "1.56") );
console.log( cmpVersion( "1.65", "1.5.6") );
console.log( cmpVersion( "1.0", "1.5.6b3") );
函数cmpVersion(v1、v2){
如果(v1==v2)返回0;
var a1=v1.toString().split(“.”);
var a2=v2.toString().split(“.”);
对于(变量i=0;i0){
返回1;
}
else if(diff0)?1:(diff函数cmpVersion(a,b){
var i、cmp、len;
a=(a+)。拆分('.');
b=(b+)。拆分('.');
len=数学最大值(a.长度,b.长度);
对于(i=0;i=0;
}
功能版本(a、b){
返回cmpVersion(a,b)<0;
}
此函数用于处理:
- 数字或字符串作为输入
- 尾随零(例如
cmpVersion(“1.0”,1)
返回0
)
- 忽略尾随的
alpha
,b
,pre4
等
如果您想完全正确,请查看关于的讨论,尤其是标题“新版本控制算法”
否则,您的答案似乎很好。npm使用了一种很好的语法来比较版本,您可以在这里获得相同的模块:
function compareVersion(a, b) {
return compareVersionRecursive(a.split("."), b.split("."));
}
function compareVersionRecursive(a, b) {
if (a.length == 0) {
a = [0];
}
if (b.length == 0) {
b = [0];
}
if (a[0] != b[0] || (a.length == 1 && b.length == 1)) {
return a[0] - b[0];
}
return compareVersionRecursive(a.slice(1), b.slice(1));
}
支持以下范围样式:
1.2.3
一个特定的版本。当没有其他功能时。请注意,构建元数据仍然被忽略,因此1.2.3+build2012
将满足此范围
>1.2.3
大于特定版本
=1.2.3
大于或等于。请注意,预发布版本不等于其“正常”等效版本,因此1.2.3-beta
将不满足此范围,但2.3.0-beta
将满足此范围
=1.2.3=1.2.3-0=1.2.3-0=0.1.3-0=1.2.0-0=1.2.0-0=1.0.0-0=1.0.0-0=1.0.0-0=1.0.0-0如果版本大于或等于最低版本,则此函数返回true。如果版本是字符串,则假定1.0大于1。如果是数字,则表示它们相同。如果希望两种类型返回相同,则返回相同的值您需要将数字转换为字符串,这也很容易。或者您可以修改字符串条件,以检查较长版本号是否具有所有尾随零,如1.1 vs 1.1.0.0.0。第二个版本号是所有尾随零
function doesMyVersionMeetMinimum(myVersion, minimumVersion) {
if(typeof myVersion === 'number' && typeof minimumVersion === 'number') {
return(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 false;
}
else if(Number(v1[i]) < Number(v2[i])) {
return true;
}
}
return (v1.length >= v2.length);
}
函数doesMyVersionMeetMinimum(myVersion,minimumVersion){
如果(myVersion的类型=='number'&&typeof minimumVersion==='number'){
返回(myVersion>=最小版本);
}
var v1=myVersion.split(“.”),v2=minimumVersion.split(“.”),minLength;
minLength=数学最小值(v1.length,v2.length);
对于(i=0;i=v2.长度);
}
我已经对我的代码进行了重构,使其尽可能简洁。它不检查尾随的零,但适用于任何长度的构建编号(例如,major、major.minor、major.minor.build)
var cmpVersion=函数(a,b){
设arrA=Array.from(a.split('.'),i=>+i);
设arrB=Array.from(b.split('.'),i=>+i);
对于(设i=0;i<(arrA.length>=arrB.length?arrA.length:arrB.length);i++){
if(arrA[i]&&!arrB[i]| | arrA[i]>arrB[i])返回“少于一”;
否则如果(!arrA[i]&&arrB[i]| | arrA[i]
基本上,首先我用每个版本字符串创建了一个新数组,这样我就可以单独比较每个数字。然后在for循环中,我选择最长版本字符串的长度(如果它们的长度相等,则选择第一个版本字符串的长度)
if语句检查a中是否有数字而b中没有,或者a的数字是否大于对应占位符的b的数字,在这种情况下,它将返回“小于1”
另外,else语句检查b中是否有数字,而a中没有,或者对于相应的位置值,b的数字是否大于a的数字,在这种情况下,它将返回“大于1”
最后一个return 0语句是一个catch all语句,如果版本字符串相等,我们的函数将使用该语句。我已经创建了以下函数,它支持尾随字母、前导零…(请参见下面的示例):
如果您不需要支持前导零,这里有一个更简单的选择:
function cmpVersions(a, b) {
function padParts(version) {
return version
.split('.')
.map(function (part) {
return '00000000'.substr(0, 8 - part.length) + part;
})
.join('.');
}
a = padParts(a);
b = padParts(b);
return a.localeCompare(b);
}
快速更新:我后来注意到,第一个函数将“1.2”排序在“1.10”之前,这显然是错误的。此外,“重要的前导零”非常棘手且不明确(无论是解释还是实现),语义版本控制都显式避免了它们。因此,我认为第二个函数应该始终是首选函数
更新2:但第二个函数在“1.1”之前排序为“1.2a”…我认为没有“一刀切”的函数…根据
function doesMyVersionMeetMinimum(myVersion, minimumVersion) {
if(typeof myVersion === 'number' && typeof minimumVersion === 'number') {
return(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 false;
}
else if(Number(v1[i]) < Number(v2[i])) {
return true;
}
}
return (v1.length >= v2.length);
}
var cmpVersion = function(a, b) {
let arrA = Array.from(a.split('.'), i => +i);
let arrB = Array.from(b.split('.'), i => +i);
for (let i = 0; i < (arrA.length >= arrB.length ? arrA.length : arrB.length); i++) {
if (arrA[i] && !arrB[i] || arrA[i] > arrB[i]) return 'less than one';
else if (!arrA[i] && arrB[i] || arrA[i] < arrB[i]) return 'greater than one';
}
return 0;
}
function cmpVersions(a, b) {
var partsA = a.split('.');
var partsB = b.split('.');
var nbParts = Math.max(partsA.length, partsB.length);
for (var i = 0; i < nbParts; ++i) {
if (partsA[i] === undefined) {
partsA[i] = '0';
}
if (partsB[i] === undefined) {
partsB[i] = '0';
}
// edit: added this part
// - fixes the important case "1.2 / 1.10"
// - but breaks the not-so-important case "1.02 / 1.1"
var intA = parseInt(partsA[i], 10);
var intB = parseInt(partsB[i], 10);
if (!isNaN(intA) && !isNaN(intB)) {
if (intA > intB) {
return 1;
} else if (intA < intB) {
return -1;
}
}
var compare = partsA[i].localeCompare(partsB[i]);
if (compare !== 0) {
return compare;
}
}
return 0;
}
// trailing letters
cmpVersion('1.0a', '1.0b'); // -1
// leading zeroes
cmpVersion('1.01', '1.1'); // -1
// "zero" parts
cmpVersion('1', '1.0'); // 0
function cmpVersions(a, b) {
function padParts(version) {
return version
.split('.')
.map(function (part) {
return '00000000'.substr(0, 8 - part.length) + part;
})
.join('.');
}
a = padParts(a);
b = padParts(b);
return a.localeCompare(b);
}