以下是软件版本号:
"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"
这样可以更清楚地看到背后的想法。
但是,我怎样才能把它转换成计算机程序呢?
// Return 1 if a > b
// Return -1 if a < b
// Return 0 if a == b
function compare(a, b) {
if (a === b) {
return 0;
}
var a_components = a.split(".");
var b_components = b.split(".");
var len = Math.min(a_components.length, b_components.length);
// loop while the components are equal
for (var i = 0; i < len; i++) {
// A bigger than B
if (parseInt(a_components[i]) > parseInt(b_components[i])) {
return 1;
}
// B bigger than A
if (parseInt(a_components[i]) < parseInt(b_components[i])) {
return -1;
}
}
// If one's a prefix of the other, the longer one is greater.
if (a_components.length > b_components.length) {
return 1;
}
if (a_components.length < b_components.length) {
return -1;
}
// Otherwise they are the same.
return 0;
}
console.log(compare("1", "2"));
console.log(compare("2", "1"));
console.log(compare("1.0", "1.0"));
console.log(compare("2.0", "1.0"));
console.log(compare("1.0", "2.0"));
console.log(compare("1.0.1", "1.0"));
我已经创建了这个解决方案,我希望你觉得它有用:
https://runkit.com/ecancino/5f3c6c59593d23001485992e
const quantify = max => (n, i) => n * (+max.slice(0, max.length - i))
const add = (a, b) => a + b
const calc = s => s.
split('.').
map(quantify('1000000')).
reduce(add, 0)
const sortVersions = unsortedVersions => unsortedVersions
.map(version => ({ version, order: calc(version) }))
.sort((a, b) => a.order - b.order)
.reverse()
.map(o => o.version)
我找到了最简单的方法来比较它们,但我不确定这是否是你想要的。
当我在控制台中运行下面的代码时,它是有意义的,并且使用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"]
下面是一个版本,它对版本字符串进行排序,而不分配任何子字符串或数组。由于它分配的对象更少,GC要做的工作也就更少。
有一对分配(允许重用getVersionPart方法),但是如果您对性能非常敏感,您可以扩展它以完全避免分配。
const compareVersionStrings : (a: string, b: string) => number = (a, b) =>
{
var ia = {s:a,i:0}, ib = {s:b,i:0};
while (true)
{
var na = getVersionPart(ia), nb = getVersionPart(ib);
if (na === null && nb === null)
return 0;
if (na === null)
return -1;
if (nb === null)
return 1;
if (na > nb)
return 1;
if (na < nb)
return -1;
}
};
const zeroCharCode = '0'.charCodeAt(0);
const getVersionPart = (a : {s:string, i:number}) =>
{
if (a.i >= a.s.length)
return null;
var n = 0;
while (a.i < a.s.length)
{
if (a.s[a.i] === '.')
{
a.i++;
break;
}
n *= 10;
n += a.s.charCodeAt(a.i) - zeroCharCode;
a.i++;
}
return n;
}
// Return 1 if a > b
// Return -1 if a < b
// Return 0 if a == b
function compare(a, b) {
if (a === b) {
return 0;
}
var a_components = a.split(".");
var b_components = b.split(".");
var len = Math.min(a_components.length, b_components.length);
// loop while the components are equal
for (var i = 0; i < len; i++) {
// A bigger than B
if (parseInt(a_components[i]) > parseInt(b_components[i])) {
return 1;
}
// B bigger than A
if (parseInt(a_components[i]) < parseInt(b_components[i])) {
return -1;
}
}
// If one's a prefix of the other, the longer one is greater.
if (a_components.length > b_components.length) {
return 1;
}
if (a_components.length < b_components.length) {
return -1;
}
// Otherwise they are the same.
return 0;
}
console.log(compare("1", "2"));
console.log(compare("2", "1"));
console.log(compare("1.0", "1.0"));
console.log(compare("2.0", "1.0"));
console.log(compare("1.0", "2.0"));
console.log(compare("1.0.1", "1.0"));