1

I'm currently using:

last = Math.max.apply(Math, response.data.map((o: any) => {
   return o.name; 
}))

to find the object with the highest 'name' value within response.data array. Despite 16.12 being the largest value, it returns 16.9 as I think it's just looking at the 1 and skipping it. How can I make it take into account the full decimal?

Edited: The data coming through is:

enter image description here

Nats
  • 160
  • 3
  • 20
  • 5
    please add the data as well. why is `16.12` greater than `16.9`? – Nina Scholz Feb 09 '20 at 20:59
  • @NinaScholz edited to add data – Nats Feb 09 '20 at 21:03
  • i see no problem with the code. can you explain a bit more what data is giving the false result? – Nina Scholz Feb 09 '20 at 21:15
  • 2
    I think you're misunderstanding @NatalieM 16.9 is greater than 16.12, which is why you're getting that answer. – Gaurav Punjabi Feb 09 '20 at 21:15
  • Yeah given what I want, a math function might not be the most appropriate...First of all the data is referring to release versions and they come in as strings. I had converted to floats as I thought it working with them as string would be trickier. So release 16.9 is older than 16.12 but once converted into floats it isn't. I've found a work around since the first item in the data returned is the latest (16.12) which removes the need for converting. Thanks guys! – Nats Feb 09 '20 at 22:10
  • @NatalieM you should not be relying on the first is the max value – EugenSunic Feb 09 '20 at 22:15
  • Yeah I mean it's not my preferred method but when converting "16.12.3" for example I can't get the full thing – Nats Feb 09 '20 at 22:16
  • And I take it unless they are non strings I can't compare for the highest? – Nats Feb 09 '20 at 22:17

2 Answers2

1

In the context of SemVer the individual components, major, minor and patch are integers however the composite value, major.minor.patch is not a valid number itself. This is why they are stored as strings, the period is merely a delimiter and not a decimal point.

To correctly compare versions you need to break the strings into their component parts and compare each pair of numbers individually. The following example does this by sorting in descending order then taking the first value.

Note: As it is unclear from the question what exactly the requirements are, abbreviated versions e.g. 1.1, will be treated as 1.1.0 here for the sake of simplicity - where typically it is more idiomatic to say that 1.1 represents the highest version of 1.1.x available for a given set.

const cmpVersionDesc = (a, b) => {
    const as = a.split('.').map(Number)
    const bs = b.split('.').map(Number)

    return (bs[0]||0) - (as[0]||0)
        || (bs[1]||0) - (as[1]||0)
        || (bs[2]||0) - (as[2]||0)
}

const latestVersion = versions => 
    [...versions].sort(cmpVersionDesc)[0]
    
 const versions = [
    '16.9',
    '16.12',
    '16.12.1',
    '16.1'
]

console.log('latest', latestVersion(versions)) // '16.12.1'
Emissary
  • 9,954
  • 8
  • 54
  • 65
-1

const array = [{
    name: 16.3
  },
  {
    name: 16
  },
  {
    name: 17
  },
  {
    name: 17.3
  },
  {
    name: 19
  }
]


console.log(Math.max(...array.map(({name}) => name % 1 !== 0 && name)))
EugenSunic
  • 13,162
  • 13
  • 64
  • 86