Parsing a version number string to an associating value

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".

  • Version IDs higher than 3.2.1 will return "null"
  • Version IDs between 3.2.1 and 2.8.10 will return "testing_server"
  • Version ID of 2.8.10 will return "second_value"
  • Version IDs between 2.8.10 and 1.0.* will return "last value"
  • Version IDs matching 1.0.* or less (including 0.*) will return "last value"

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. :)


Solution 1:

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)

Solution 2:

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.