1

I have a array of version numbers looking like this:

[
  {
    "name": "v12.3.0.pre",
  },
  {
    "name": "v12.2.5",
  },
  {
    "name": "v12.2.4",
  },
  {
    "name": "v12.2.3",
  },
  {
    "name": "v12.2.1",
  },
  {
    "name": "v12.2.0",
  },
  {
    "name": "v12.2.0.pre",
  },
  {
    "name": "v12.2.0-rc32",
  },
  {
    "name": "v12.2.0-rc31",
  },
  {
    "name": "v12.1.9",
  },
  {
    "name": "v12.1.8",
  },
  {
    "name": "v12.1.6",
  },
  {
    "name": "v12.1.4",
  },
  {
    "name": "v12.1.3",
  },
  {
    "name": "v12.1.2",
  },
  {
    "name": "v12.1.1",
  },
  {
    "name": "v12.1.0",
  },
  {
    "name": "v12.1.0.pre",
  },
  {
    "name": "v12.1.0-rc23",
  },
  {
    "name": "v12.1.0-rc22",
  },
  {
    "name": "v12.0.9",
  },
  {
    "name": "v12.0.8",
  },
  {
    "name": "v12.0.6",
  },
  {
    "name": "v12.0.4",
  },
  {
    "name": "v12.0.3",
  },
  {
    "name": "v12.0.2",
  },
  {
    "name": "v12.0.1",
  },
  {
    "name": "v12.0.0",
  },
  {
    "name": "v11.12.0.pre",
  },
  {
    "name": "v11.11.8",
  }
]

From this array I would like to determine the latest version, which do not end with '.pre' or include 'rc.

I'm iterating through the array with a for-loop, and filtering out the '.pre' and 'rc' with an if statement. I then use split/join to remove the first 'v' character. So far so good. Then I'm left with values like '12.2.5' and '11.12.10'. I first thought of removing the dots, then use a 'greater than' operator to see find the highest value, but then '11.12.10(111210)' would result greater than '12.2.5(1225)' which would not work out in my case.

for(i in arr){
    if(!arr[i].name.endsWith('.pre') && !arr[i].name.includes('rc')){
        var number = number.split('v').join("");
        var number = number.split('.').join("");
    }
}

Any ideas on best way to solve this? Thanks!

objectclass
  • 154
  • 1
  • 3
  • 13
  • 3
    I think the best way is to just use a library that parses these versions. No need to reinvent the wheel here. – VLAZ Sep 20 '19 at 10:56
  • 1
    You're looking for "natural sort", e.g. https://stackoverflow.com/questions/2802341/javascript-natural-sort-of-alphanumerical-strings – georg Sep 20 '19 at 11:15

4 Answers4

8

You could take String#localeCompare with options for getting a result.

var data = [{ name: "v12.3.0.pre" }, { name: "v12.2.5" }, { name: "v12.2.4" }, { name: "v12.2.3" }, { name: "v12.2.1" }, { name: "v12.2.0" }, { name: "v12.2.0.pre" }, { name: "v12.2.0-rc32" }, { name: "v12.2.0-rc31" }, { name: "v12.1.9" }, { name: "v12.1.8" }, { name: "v12.1.6" }, { name: "v12.1.4" }, { name: "v12.1.3" }, { name: "v12.1.2" }, { name: "v12.1.1" }, { name: "v12.1.0" }, { name: "v12.1.0.pre" }, { name: "v12.1.0-rc23" }, { name: "v12.1.0-rc22" }, { name: "v12.0.9" }, { name: "v12.0.8" }, { name: "v12.0.6" }, { name: "v12.0.4" }, { name: "v12.0.3" }, { name: "v12.0.2" }, { name: "v12.0.1" }, { name: "v12.0.0" }, { name: "v11.12.0.pre" }, { name: "v11.11.8" }],
    highest = data
        .filter(({ name }) => !name.endsWith('.pre') && !name.includes('rc'))
        .reduce((a, b) =>
            0 < a.name.localeCompare(b.name, undefined, { numeric: true, sensitivity: 'base' })
                ? a
                : b
        );

console.log(highest);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • You know that's great and all, but you are explaining something rather simple and then using oddball variable declaration, and even more oddball 0 < ternary nonsense. I had to spend more time figuring that part out and rewriting it using normal mortal human brain individual line numbers than I did actually getting the highest version number. – CarComp Oct 12 '22 at 16:49
1

I think i have a solution for you: Save the numbers to arrays, so you have for the numbers '12.2.5' and '11.12.10' the following:

[12,2,5] and [11,12,10]

Then you compare the arrays. Keep the greates from the [0] position, if they're equal the greates from the [1] position and so...

Maybe it works...

Hope it helps you!!

Kind regards, Sergio.

0

Here I am not going with the logic of removing and filtering out the '.pre' and 'rc' with an if statement. then use split/join to remove the first 'v' character. Then you left with the values like '11.12.10' and '12.2.5' so, after getting these values you can use below code

You could prepend all parts to fixed-size strings, then sort that, and finally remove the padding again

Below code, the snippet is an example not for above exactly but will help you sure

var arr = ['12.2.5', '11.12.10', '12.0.6', '6.1.0', '5.1.0', '4.5.0'];
arr = arr.map( a => a.split('.').map( n => +n+100000 ).join('.') ).sort()
         .map( a => a.split('.').map( n => +n-100000 ).join('.') );

console.log(arr)
Kinjal Gor
  • 401
  • 2
  • 5
  • 15
0

The basic idea to make this comparison would be to use Array.split to get arrays of parts from the input strings and then compare pairs of parts from the two arrays; if the parts are not equal we know which version is smaller. Reference

var versionsList = [
  { "name": "v12.3.0.pre" },
  { "name": "v12.2.5" },
  { "name": "v12.2.4" },
  { "name": "v12.2.3" },
  { "name": "v12.2.1" },
  { "name": "v12.2.0" },
  { "name": "v12.2.0.pre" },
  { "name": "v12.2.0-rc32" },
  { "name": "v12.2.0-rc31" },
  { "name": "v12.1.9" },
  { "name": "v12.1.8" },
  { "name": "v12.1.6" },
  { "name": "v12.1.4" },
  { "name": "v12.1.3" },
  { "name": "v12.1.2" },
  { "name": "v12.1.1" },
  { "name": "v12.1.0" },
  { "name": "v12.1.0.pre" },
  { "name": "v12.1.0-rc23" },
  { "name": "v12.1.0-rc22" },
  { "name": "v12.0.9", },
  { "name": "v12.0.8", },
  { "name": "v12.0.6", },
  { "name": "v12.0.4", },
  { "name": "v12.0.3", },
  { "name": "v12.0.2", },
  { "name": "v12.0.1", },
  { "name": "v12.0.0", },
  { "name": "v11.12.0.pre", },
  { "name": "v11.11.8", }
];

function versionCompare(v1, v2) {
    var v1parts = v1.split('.'),
        v2parts = v2.split('.');
    for (var i=0; i<v1parts.length; i++) {
        if (v1parts[i] === v2parts[i]) {
            continue;
        }
        else if (v1parts[i] > v2parts[i]) {
            return v1;
        }
        else {
           return v2;
        }
    } 
    return v1;
}

var maxVersion;

for (i in versionsList) {
    version = versionsList[i].name;
    if (!version.endsWith('.pre') && !version.includes('rc')) {
        if (typeof maxVersion === "undefined")
          maxVersion = version.substr(1);
        var ver = version.substr(1);        
        if (ver !== maxVersion)
            maxVersion = versionCompare(ver, maxVersion);
    }
}

console.log('v'+ maxVersion);
rprakash
  • 500
  • 5
  • 10