以下是软件版本号:
"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"
这样可以更清楚地看到背后的想法。
但是,我怎样才能把它转换成计算机程序呢?
这实际上取决于版本控制系统背后的逻辑。每个数字代表什么,如何使用。
每个subversion是否是一个用于指定开发阶段的数字?
为0
1代表β
发布候选2个
3为(最终)发布
它是构建版本吗?您是否应用增量更新?
一旦了解了版本控制系统的工作原理,创建算法就变得很容易了。
如果您不允许在每个subversion中使用大于9的数字,则删除所有小数,但第一个小数将允许您进行直接比较。
如果允许在任何一种颠覆版本中使用大于9的数字,有几种方法可以比较它们。最明显的方法是将字符串按小数分割,然后比较每一列。
但是在不知道版本控制系统是如何工作的情况下,当版本1.0.2a发布时,实现像上面这样的过程可能会很麻烦。
我认为这是一个值得分享的实现,因为它简短,简单,但功能强大。请注意,它只使用数字比较。通常它会检查version2是否比version1晚,如果是,则返回true。假设您有version1: 1.1.1和version2: 1.1.2。它遍历两个版本的每个部分,将它们的部分相加如下:对于版本1(1 + 0.1)然后(1.1 + 0.01),对于版本2(1 + 0.1)然后(1.1 + 0.02)。
function compareVersions(version1, version2) {
version1 = version1.split('.');
version2 = version2.split('.');
var maxSubVersionLength = String(Math.max.apply(undefined, version1.concat(version2))).length;
var reduce = function(prev, current, index) {
return parseFloat(prev) + parseFloat('0.' + Array(index + (maxSubVersionLength - String(current).length)).join('0') + current);
};
return version1.reduce(reduce) < version2.reduce(reduce);
}
如果你想从版本列表中找到最新的版本,那么这可能是有用的:
function findLatestVersion(versions) {
if (!(versions instanceof Array)) {
versions = Array.prototype.slice.apply(arguments, [0]);
}
versions = versions.map(function(version) { return version.split('.'); });
var maxSubVersionLength = String(Math.max.apply(undefined, Array.prototype.concat.apply([], versions))).length;
var reduce = function(prev, current, index) {
return parseFloat(prev) + parseFloat('0.' + Array(index + (maxSubVersionLength - String(current).length)).join('0') + current);
};
var sums = [];
for (var i = 0; i < versions.length; i++) {
sums.push(parseFloat(versions[i].reduce(reduce)));
}
return versions[sums.indexOf(Math.max.apply(undefined, sums))].join('.');
}
console.log(findLatestVersion('0.1000000.1', '2.0.0.10', '1.6.10', '1.4.3', '2', '2.0.0.1')); // 2.0.0.10
console.log(findLatestVersion(['0.1000000.1', '2.0.0.10', '1.6.10', '1.4.3', '2', '2.0.0.1'])); // 2.0.0.10
这是一个巧妙的技巧。如果您正在处理数值,在特定的值范围内,您可以为版本对象的每个级别分配一个值。例如,“largestValue”在这里被设置为0xFF,这为您的版本控制创建了一个非常“IP”的外观。
这也处理字母-数字版本(即1.2a < 1.2b)
// The version compare function
function compareVersion(data0, data1, levels) {
function getVersionHash(version) {
var value = 0;
version = version.split(".").map(function (a) {
var n = parseInt(a);
var letter = a.replace(n, "");
if (letter) {
return n + letter[0].charCodeAt() / 0xFF;
} else {
return n;
}
});
for (var i = 0; i < version.length; ++i) {
if (levels === i) break;
value += version[i] / 0xFF * Math.pow(0xFF, levels - i + 1);
}
return value;
};
var v1 = getVersionHash(data0);
var v2 = getVersionHash(data1);
return v1 === v2 ? -1 : v1 > v2 ? 0 : 1;
};
// Returns 0 or 1, correlating to input A and input B
// Direct match returns -1
var version = compareVersion("1.254.253", "1.254.253a", 3);
我必须比较我的扩展版本,但我没有
在这里找到一个可行的解决方案。在比较1.89 > 1.9或1.24.1 == 1.240.1时,几乎所有提议的期权都被打破了
这里,我从仅在最后的记录1.1 == 1.10和1.10.1 > 1.1.1中0下降的事实开始
compare_version = (new_version, old_version) => {
new_version = new_version.split('.');
old_version = old_version.split('.');
for(let i = 0, m = Math.max(new_version.length, old_version.length); i<m; i++){
//compare text
let new_part = (i<m-1?'':'.') + (new_version[i] || 0)
, old_part = (i<m-1?'':'.') + (old_version[i] || 0);
//compare number (I don’t know what better)
//let new_part = +((i<m-1?0:'.') + new_version[i]) || 0
//, old_part = +((i<m-1?0:'.') + old_version[i]) || 0;
//console.log(new_part, old_part);
if(old_part > new_part)return 0; //change to -1 for sort the array
if(new_part > old_part)return 1
}
return 0
};
compare_version('1.0.240.1','1.0.240.1'); //0
compare_version('1.0.24.1','1.0.240.1'); //0
compare_version('1.0.240.89','1.0.240.9'); //0
compare_version('1.0.24.1','1.0.24'); //1
我不是一个大专家,但我构建了简单的代码来比较两个版本,将第一个返回值更改为-1以对版本数组进行排序
['1.0.240', '1.0.24', '1.0.240.9', '1.0.240.89'].sort(compare_version)
//results ["1.0.24", "1.0.240", "1.0.240.89", "1.0.240.9"]
和短版本的比较全字符串
c=e=>e.split('.').map((e,i,a)=>e[i<a.length-1?'padStart':'padEnd'](5)).join('');
//results " 1 0 2409 " > " 1 0 24089 "
c('1.0.240.9')>c('1.0.240.89') //true
如果您有意见或改进,请不要犹豫提出建议。