将版本号字符串解析为关联值
Parsing a version number string to an associating value
我正在尝试解析版本字符串(下面的示例),以便 return 一个值取决于与下面列出的以下规则匹配的键。
每个版本 ID 都可以包含一个通配符,但输入不能。当然这个对象是动态的并且很可能包含更多版本匹配。
在此示例中,版本字符串将为“1.2.3”。
- 高于 3.2.1 的版本 ID 将 return“空”
- 3.2.1 和 2.8.10 之间的版本 ID 将 return“testing_server”
- 2.8.10 的版本 ID 将 return“second_value”
- 2.8.10 和 1.0 之间的版本 ID。* 将 return“最后一个值”
- 匹配 1.0.* 或更低(包括 0.*)的版本 ID 将 return“最后一个值”
示例对象:
{
"3.2.1": "testing_server",
"2.8.10": "second_value",
"1.0.*": "last value"
}
我尝试了几个函数,每个函数都包括正则表达式或手动比较,但没有取得太大的成功。我知道这有点困难,但希望有人能提供帮助。 :)
这是一个开始。
const versions = {
"4": null,
"3.2.1": "testing_server",
"2.8.10": "second_value",
"1.0.*": "last value"
}
const maxLength = 3
const getLiteral = (versions,version) => {
return Object.entries(versions).filter(([key,val]) => {
const parts = key.split(".").map(part => part.padStart(maxLength,"0")).join(".")
const vparts = version.split(".").map(part => part.padStart(maxLength,"0")).join(".")
console.log(vparts,parts,vparts > parts)
return vparts > parts
}).flat()[1] || null
};
let verText = getLiteral(versions,"1.2.3")
console.log(verText)
verText = getLiteral(versions,"4.2.3")
console.log(verText)
我会使用这样的函数来使版本字符串具有可比性:
function comparableValue(versionString) {
const digits = versionString.split(".");
digits.reverse();
let value = 0;
for (let i = 0; i < digits.length; i++) {
value += Math.pow(1000, i) * digits[i];
}
return value;
}
function classify(wildcard, value) {
const boundaries = {
"3.2.1": "testing_server",
"2.8.10": "second_value",
};
const lowestBoundary = `1.0.${wildcard}`;
boundaries[lowestBoundary] = "last_value";
const keys = Object.keys(boundaries);
keys.sort(function(a, b) {
return comparableValue(a) - comparableValue(b);
});
for (const key of keys) {
if (comparableValue(value) < comparableValue(key)) {
return boundaries[key];
}
}
return null;
}
const examples = [
"3.5.5",
"3.1.1",
"2.10.10",
"2.8.8",
"1.1.1",
"0.4.2",
];
const answers = {};
for (const example of examples) {
answers[example] = classify(3, example);
}
console.log(answers);
将每个 1.1.1 样式版本转换为可比值,使每个数字的价值为右侧数字的 1000 倍。由于数字永远不会达到 1000,因此它应该始终有效。 800 或 258 也可以,只是打印出可比较的数字会使调试变得更加困难。
然后,如果我没理解错的话,我会让排序函数将通配符的值作为参数。
我最终使用“compare-versions”以及一些逻辑来实现它。
const compareVersions = require('compare-versions');
function getVersion(version) {
const versions = {
"3.2.1": "testing_server",
"2.8.10": "second_value",
"1.0.*": "last value"
}
const sortedKeys = Object.keys(versions).sort(compareVersions);
// not required
//if (compareVersions(version, sortedKeys[sortedKeys.length - 1]) > 0) return null;
let i = 0;
while (i < sortedKeys.length && compareVersions(version, sortedKeys[i]) > 0) i++;
return versions[sortedKeys[i]] || null;
}
const examples = [
"3.2.2",
"3.2.1",
"2.8.11",
"2.8.10",
"1.1.0",
"1.0",
"0.0"
];
const answers = {};
for (const example of examples) {
answers[example] = getVersion(example);
}
console.log(answers);
我正在尝试解析版本字符串(下面的示例),以便 return 一个值取决于与下面列出的以下规则匹配的键。
每个版本 ID 都可以包含一个通配符,但输入不能。当然这个对象是动态的并且很可能包含更多版本匹配。
在此示例中,版本字符串将为“1.2.3”。
- 高于 3.2.1 的版本 ID 将 return“空”
- 3.2.1 和 2.8.10 之间的版本 ID 将 return“testing_server”
- 2.8.10 的版本 ID 将 return“second_value”
- 2.8.10 和 1.0 之间的版本 ID。* 将 return“最后一个值”
- 匹配 1.0.* 或更低(包括 0.*)的版本 ID 将 return“最后一个值”
示例对象:
{
"3.2.1": "testing_server",
"2.8.10": "second_value",
"1.0.*": "last value"
}
我尝试了几个函数,每个函数都包括正则表达式或手动比较,但没有取得太大的成功。我知道这有点困难,但希望有人能提供帮助。 :)
这是一个开始。
const versions = {
"4": null,
"3.2.1": "testing_server",
"2.8.10": "second_value",
"1.0.*": "last value"
}
const maxLength = 3
const getLiteral = (versions,version) => {
return Object.entries(versions).filter(([key,val]) => {
const parts = key.split(".").map(part => part.padStart(maxLength,"0")).join(".")
const vparts = version.split(".").map(part => part.padStart(maxLength,"0")).join(".")
console.log(vparts,parts,vparts > parts)
return vparts > parts
}).flat()[1] || null
};
let verText = getLiteral(versions,"1.2.3")
console.log(verText)
verText = getLiteral(versions,"4.2.3")
console.log(verText)
我会使用这样的函数来使版本字符串具有可比性:
function comparableValue(versionString) {
const digits = versionString.split(".");
digits.reverse();
let value = 0;
for (let i = 0; i < digits.length; i++) {
value += Math.pow(1000, i) * digits[i];
}
return value;
}
function classify(wildcard, value) {
const boundaries = {
"3.2.1": "testing_server",
"2.8.10": "second_value",
};
const lowestBoundary = `1.0.${wildcard}`;
boundaries[lowestBoundary] = "last_value";
const keys = Object.keys(boundaries);
keys.sort(function(a, b) {
return comparableValue(a) - comparableValue(b);
});
for (const key of keys) {
if (comparableValue(value) < comparableValue(key)) {
return boundaries[key];
}
}
return null;
}
const examples = [
"3.5.5",
"3.1.1",
"2.10.10",
"2.8.8",
"1.1.1",
"0.4.2",
];
const answers = {};
for (const example of examples) {
answers[example] = classify(3, example);
}
console.log(answers);
将每个 1.1.1 样式版本转换为可比值,使每个数字的价值为右侧数字的 1000 倍。由于数字永远不会达到 1000,因此它应该始终有效。 800 或 258 也可以,只是打印出可比较的数字会使调试变得更加困难。
然后,如果我没理解错的话,我会让排序函数将通配符的值作为参数。
我最终使用“compare-versions”以及一些逻辑来实现它。
const compareVersions = require('compare-versions');
function getVersion(version) {
const versions = {
"3.2.1": "testing_server",
"2.8.10": "second_value",
"1.0.*": "last value"
}
const sortedKeys = Object.keys(versions).sort(compareVersions);
// not required
//if (compareVersions(version, sortedKeys[sortedKeys.length - 1]) > 0) return null;
let i = 0;
while (i < sortedKeys.length && compareVersions(version, sortedKeys[i]) > 0) i++;
return versions[sortedKeys[i]] || null;
}
const examples = [
"3.2.2",
"3.2.1",
"2.8.11",
"2.8.10",
"1.1.0",
"1.0",
"0.0"
];
const answers = {};
for (const example of examples) {
answers[example] = getVersion(example);
}
console.log(answers);