以下是软件版本号:
"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"
这样可以更清楚地看到背后的想法。
但是,我怎样才能把它转换成计算机程序呢?
2017答:
v1 = '20.0.12';
v2 = '3.123.12';
compareVersions(v1,v2)
// return positive: v1 > v2, zero:v1 == v2, negative: v1 < v2
function compareVersions(v1, v2) {
v1= v1.split('.')
v2= v2.split('.')
var len = Math.max(v1.length,v2.length)
/*default is true*/
for( let i=0; i < len; i++)
v1 = Number(v1[i] || 0);
v2 = Number(v2[i] || 0);
if (v1 !== v2) return v1 - v2 ;
i++;
}
return 0;
}
最简单的现代浏览器代码:
function compareVersion2(ver1, ver2) {
ver1 = ver1.split('.').map( s => s.padStart(10) ).join('.');
ver2 = ver2.split('.').map( s => s.padStart(10) ).join('.');
return ver1 <= ver2;
}
这里的想法是比较数字,但以字符串的形式。为了使比较工作,两个字符串必须在相同的长度。所以:
"123" > "99"变成"123" > "099"
填充短数字“修复”比较
这里我用0填充每个部分,长度为10。然后使用简单的字符串比较来得到答案
例子:
var ver1 = '0.2.10', ver2=`0.10.2`
//become
ver1 = '0000000000.0000000002.0000000010'
ver2 = '0000000000.0000000010.0000000002'
// then it easy to see that
ver1 <= ver2 // true
我找到了最简单的方法来比较它们,但我不确定这是否是你想要的。
当我在控制台中运行下面的代码时,它是有意义的,并且使用sort()方法,我可以获得版本字符串的排序数组。它是根据字母顺序排列的。
"1.0" < "1.0.1" //true
var arr = ["1.0.1", "1.0", "3.2.0", "1.3"]
arr.sort(); //["1.0", "1.0.1", "1.3", "3.2.0"]
这里找不到我想要的函数。所以我自己写了。这就是我的贡献。我希望有人觉得它有用。
优点:
处理任意长度的版本字符串。'1'或'1.1.1.1.1'。
如果没有指定,则默认为0。仅仅因为字符串更长并不意味着它是一个更大的版本。(“1”应与“1.0”和“1.0.0.0”相同。)
比较数字而不是字符串。('3'<'21'应为真。不是假的。)
不要把时间浪费在无用的比较上。(比较for ==)
你可以选择你自己的比较器。
缺点:
它不处理版本字符串中的字母。(我不知道这是怎么回事?)
我的代码,类似于Jon接受的答案:
function compareVersions(v1, comparator, v2) {
"use strict";
var comparator = comparator == '=' ? '==' : comparator;
if(['==','===','<','<=','>','>=','!=','!=='].indexOf(comparator) == -1) {
throw new Error('Invalid comparator. ' + comparator);
}
var v1parts = v1.split('.'), v2parts = v2.split('.');
var maxLen = Math.max(v1parts.length, v2parts.length);
var part1, part2;
var cmp = 0;
for(var i = 0; i < maxLen && !cmp; i++) {
part1 = parseInt(v1parts[i], 10) || 0;
part2 = parseInt(v2parts[i], 10) || 0;
if(part1 < part2)
cmp = 1;
if(part1 > part2)
cmp = -1;
}
return eval('0' + comparator + cmp);
}
例子:
compareVersions('1.2.0', '==', '1.2'); // true
compareVersions('00001', '==', '1.0.0'); // true
compareVersions('1.2.0', '<=', '1.2'); // true
compareVersions('2.2.0', '<=', '1.2'); // false
你不能把它们转换成数字,然后按大小排序吗?在长度< 4的数的1后面加上0
在主机上玩:
$(["1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1", "3.0"]).each(function(i,e) {
var n = e.replace(/\./g,"");
while(n.length < 4) n+="0" ;
num.push( +n )
});
版本越大,数字越大。
编辑:可能需要调整,以考虑更大的版本系列
semver
npm使用的语义版本解析器。
$ npm install semver
var semver = require('semver');
semver.diff('3.4.5', '4.3.7') //'major'
semver.diff('3.4.5', '3.3.7') //'minor'
semver.gte('3.4.8', '3.4.7') //true
semver.ltr('3.4.8', '3.4.7') //false
semver.valid('1.2.3') // '1.2.3'
semver.valid('a.b.c') // null
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true
var versions = [ '1.2.3', '3.4.5', '1.0.2' ]
var max = versions.sort(semver.rcompare)[0]
var min = versions.sort(semver.compare)[0]
var max = semver.maxSatisfying(versions, '*')
语义版本控制链接:https://www.npmjs.com/package/semver#prerelease-identifiers