简化 semver 版本比较逻辑

Posted

技术标签:

【中文标题】简化 semver 版本比较逻辑【英文标题】:Simplify semver version compare logic 【发布时间】: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() 中的逻辑。

【问题讨论】:

【参考方案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 部分的正数。(或者,可能更好的是,使用数组方法来查找第一个不同的部分)

以上是关于简化 semver 版本比较逻辑的主要内容,如果未能解决你的问题,请参考以下文章

NSIS安装打包程序的版本比较方便做后续逻辑处理

NSIS安装打包程序的版本比较方便做后续逻辑处理

我怎样才能简化这个逻辑

2简化逻辑和循环

数字电路与系统-逻辑运算与简化(常用三个公式)

autojs实现ui和逻辑分离,简化业务逻辑