最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript find highest version from array of dotted versions - Stack Overflow

programmeradmin1浏览0评论

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!

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!

Share asked Sep 20, 2019 at 10:54 objectclassobjectclass 2241 gold badge6 silver badges21 bronze badges 2
  • 3 I think the best way is to just use a library that parses these versions. No need to reinvent the wheel here. – VLAZ Commented Sep 20, 2019 at 10:56
  • 1 You're looking for "natural sort", e.g. stackoverflow./questions/2802341/… – georg Commented Sep 20, 2019 at 11:15
Add a ment  | 

4 Answers 4

Reset to default 9

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; }

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

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)

The basic idea to make this parison would be to use Array.split to get arrays of parts from the input strings and then pare 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);

发布评论

评论列表(0)

  1. 暂无评论