如何使用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. 如何比较每对中的部件?问题想要在数字上进行比较,但是如果我们的版本字符串不仅仅由数字组成(例如“1.0a”)怎么办?
  2. 如果一个版本字符串的部分多于另一个版本,会发生什么?最有可能“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.mapArray.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码识别/车架号识别/车辆唯一编码识别/车辆信息识别提取

VIN码识别/车架号识别/车辆唯一编码识别/车辆信息识别提取

js 比较版本号

js实现软件版本号的比较

说一说VIN码识别,车架号识别那些事

如何查看安卓手机硬件ID