【问题标题】:Simplify semver version compare logic简化 semver 版本比较逻辑
【发布时间】:2019-08-23 06:40:05
【问题描述】:

这里有标准的 npm semver 版本比较库,但是我这里有一些简单的逻辑来比较 semver 版本:

const versionA = '14.8.3';
const versionB = '15.1.1';
const versionC = '15.1.2';

const semver = require('semver');
const assert = require('assert');

const isGreater = (a, b) => {

  const [majorA, minorA, patchA] = String(a).split('.').map(v => Number.parseInt(v));
  const [majorB, minorB, patchB] = String(b).split('.').map(v => Number.parseInt(v));


  if (majorA > majorB) {
    return true;
  }

  if (majorB > minorA) {
    return false;
  }

  if (minorA > minorB) {
    return true;
  }

  if (minorB > minorA) {
    return false;
  }

  if (patchA > patchB) {
    return true;
  }

  if (patchB > patchA) {
    return false;
  }

  return false;

};


assert(isGreater(versionB, versionA), 'version b should be greater.');
assert(isGreater(versionA, versionB), 'version b should be greater.');

我的问题是 - 有没有办法简化大于函数中的逻辑?这个函数应该复制 semver.gt() 中的逻辑。

【问题讨论】:

    标签: javascript node.js semantic-versioning


    【解决方案1】:

    您可以使用localeCompare 代替numeric 选项(使用numeric,比较是这样的“1”

    const versionA = '14.8.3';
    const versionB = '15.1.1';
    const versionC = '15.1.2';
    const versionD = '15.1.10';
    const versionE = '15.2.1';
    const versionF = '15.11.1';
    
    const isGreater = (a, b) => {
      return a.localeCompare(b, undefined, { numeric: true }) === 1;
    };
    
    // first argument version comes later than second argument:
    console.log(isGreater(versionB, versionA));
    console.log(isGreater(versionC, versionB));
    console.log(isGreater(versionD, versionC));
    console.log(isGreater(versionE, versionD));
    console.log(isGreater(versionF, versionE));
    
    console.log('---');
    
    // second comes before first:
    console.log(isGreater(versionA, versionB));
    
    // same, return value should be false:
    console.log(isGreater(versionA, versionA));

    或者,等效地,您可以传递语言环境字符串

    en-US-u-kn-true
    

    作为第二个参数而不是{ numeric: true }

    【讨论】:

    • { numeric: true }) === -1 ? false : true 对于isGreater 应该是{ numeric: true }) === 1 ? true : false ...你的函数现在所做的是isGreaterOrEqual
    【解决方案2】:

    我相信这在逻辑上是相同的并且更短,但它的简单性并不令人惊叹

    const isGreater = (a, b) => {
    
      const [majorA, minorA, patchA] = String(a).split('.').map(v => Number.parseInt(v));
      const [majorB, minorB, patchB] = String(b).split('.').map(v => Number.parseInt(v));
    
      if (majorA !== majorB) {
        return majorA > majorB;
      }
    
      if (minorA !== minorB) {
        return minorA > minorB;
      }
    
      return patchA > patchB;
    
    };
    

    【讨论】:

    • 您可以通过.map(Number) 进行一些简化(并且ab 已经是字符串,因此如果您不想再次转换它们,则无需再次转换)。您可以将差异与|| 进行比较以简化:(majorA - majorB) || (minorA - minorB) || (patchA - patchB),这将导致第一个大于 B 的 A 部分的正数。(或者,可能更好的是,使用数组方法来查找第一个不同的部分)
    猜你喜欢
    • 2019-03-16
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多