I have this array of semver versions:
let versions = ['4.5.0', '4.5.1', '4.5.2', '4.6.0', '4.6.1', '4.6.2', '4.7.0', '4.7.1', '4.8.0', '4.8.1']
I want to filter this array and keep only the latest patch versions based on minor and major versions.
Expected result:
['4.5.2', '4.6.2', '4.7.1', '4.8.1']
I tried to check every version in two loops comparing major and minor versions, but every time I have duplicates and lower versions in the final array.
My code:
for (let versions of supportedReleaseList) {
for (let doubleCheckVersion of supportedReleaseList) {
if (semver.parse(versions).major === semver.parse(doubleCheckVersion).major) {
if (semver.parse(versions).minor === semver.parse(doubleCheckVersion).minor) {
if (semver.parse(versions).patch > semver.parse(doubleCheckVersion).patch) {
finalList.push(versions);
}
}
}
}
}
And the result was:
['4.5.1', '4.5.2', '4.5.2', '4.6.1', '4.6.2', '4.6.2', '4.7.1', '4.8.1']
I would do something like this. It will work regardless of whether the input list is ordered or not:
const semver = require('semver');
const versions = [
'4.5.0', '4.5.1', '4.5.2',
'4.6.0', '4.6.1', '4.6.2',
'4.7.0', '4.7.1',
'4.8.0', '4.8.1'
];
const latestMinorVersions = new Map();
for ( const v of versions.map( semver.parse ) ) {
const baseVersion = new semver.SemVer(`${v.major}.${v.minor}.0`).toString();
if ( !latestMinorVersions.has( baseVersion ) ) {
latestMinorVersions.set( baseVersion, v );
}
const maxVersion = latestMinorVersions.get( baseVersion );
const cc = maxVersion.compare( v );
if ( cc < 0 ) {
latestMinorVersions.set(baseVersion, v);
}
}
console.log(Array.from(latestMinorVersions.values()).map(v => v.toString()));
It produces the desired ['4.5.2', '4.6.2', '4.7.1', '4.8.1']
.
Note that if your versions
array contains prerelease and/or build metadata like 1.2.3-beta
, 1.2.3+456
, or 1.2.3.beta+456
, this may not work as expected: I would recommend testing those edge cases.