Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何比较任意版本号?_Javascript_Comparison - Fatal编程技术网

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

有人有代码来比较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 > 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);
    }