I'm attempting to parse a version string (examples below) in order to return a value depending on a key that matches the following rules listed below.
Each version ID can include a wildcard, however the input cannot. Ofcourse this object is dynamic and will most likely include more version matches.
In this example, the version string will be "1.2.3".
Example object:
{
"3.2.1": "testing_server",
"2.8.10": "second_value",
"1.0.*": "last value"
}
I have tried several functions each including regex, or manual comparisons but haven't achieved much luck. I know its a bit of a tough one, but hopefully someone can help. :)
I would use a function like this to make the version string comparable:
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);
convert each 1.1.1 style version into a comparable value by making each digital worth 1000 times as much as the one to the right. Since the numbers will never get up to 1000, it should always work. 800 or 258 would work too, except it makes it harder to debug by printing out the comparable numbers.
Then, if I understand correctly, I would make the sort function take the value of the wildcard as an argument.
Here is a start.
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)
I ended up using "compare-versions" along with some logic to get it going.
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);