1

I have an object for a document library. In the object, there is a DCN number for each document and a version number. There are multiple DCN entries and I need to filter out the highest version number for each DCN. I am not sure how to go about doing this in JavaScript. An example of the array is below:

[
  {
    'DCN': '1234567',
    'Version': 1.0
  },
  {
    'DCN': '1234567',
    'Version': 2.0
  },
  {
    'DCN': '1234567',
    'Version': 3.0
  },
  {
    'DCN': '1234567',
    'Version': 4.0
  },
  {
    'DCN': '1234568',
    'Version': 1.0
  },
  {
    'DCN': '1234568',
    'Version': 2.0
  },
  {
    'DCN': '1234568',
    'Version': 3.0
  },
  {
    'DCN': '1234568',
    'Version': 4.0
  },
  {
    'DCN': '1234569',
    'Version': 3.0
  },
  {
    'DCN': '1234569',
    'Version': 4.0
  }
]

The expected results would look like this:

[
  {
    'DCN': '1234567',
    'Version': 4.0
  },
  {
    'DCN': '1234568',
    'Version': 4.0
  },
  {
    'DCN': '1234569',
    'Version': 4.0
  }
]
Nitheesh
  • 19,238
  • 3
  • 22
  • 49
NerdyDriod
  • 67
  • 8
  • 1
    Are the version numbers being stored as floats? I would suppose there is no intention to support the semantic versioning nomenclature, e.g. `major.minor.patch` (which needs to be stored as string and not as a number/float). – Terry Jun 22 '21 at 12:16
  • So if you, for example, have `4.0.1` and `4.1.0`, I suppose you'd want `4.1.0` (as it is the higher version number)? – Terry Jun 22 '21 at 12:18
  • They are strings but I was going to convert them to number/float – NerdyDriod Jun 22 '21 at 12:18
  • @Terry yes, that is correct. 4.1.0 would be the highest version – NerdyDriod Jun 22 '21 at 12:19
  • _"I was going to convert them to number/float"_ - Which is fine for just `major.minor` but not for fuller versioning schemes – Jamiec Jun 22 '21 at 12:19
  • @Teemu I tried to use that a couple of times and it cutting off the object so I used the block quote instead. Thanks for fixing it. – NerdyDriod Jun 22 '21 at 12:20
  • 1
    Actually even `major.minor` version converted to float is problematic think of version `"4.1"` vs `"4.10"` - what happens when you convert both to float – Jamiec Jun 22 '21 at 12:20
  • @Jamiec that is a good point. would 4.01 be better than 4.1? – NerdyDriod Jun 22 '21 at 12:22
  • see: [removing duplicate objects in an array, keeping ones with maximum property value](https://stackoverflow.com/questions/45310384/removing-duplicate-objects-in-an-array-keeping-ones-with-maximum-property-value) and [How to compare software version number using js? (only number)](https://stackoverflow.com/questions/6832596/how-to-compare-software-version-number-using-js-only-number) – pilchard Jun 22 '21 at 12:23
  • Yes, that would at least solve that issue - and only becomes an issue again when you get to minor version 100. This is all notwithstanding that version numbers are often 3 or 4 sections long like `4.1.1` or `4.7.23.97052` – Jamiec Jun 22 '21 at 12:23
  • Version semantics/data types aside, `reduce` is a good option for vanilla Javascript. – Mark Peters Jun 22 '21 at 12:24
  • For semver comparison, you can use `localeCompare` to do the job: https://stackoverflow.com/questions/55466274/simplify-semver-version-compare-logic – Terry Jun 22 '21 at 12:32

2 Answers2

1

I will provide an example here:

First you convert your data-structure from an array to a map, where the keys are the DCN values and the values are arrays of all the version numbers for that DCN.

const map = {}
for (let item of <your array of objects here>) {
    if (!(item.DCN in map)) {
         map[item.DCN] = []
    }
    map[item.DCN].push(item.value)
}

You may now use the Math.max function to find the highest value of each DCN and put the result in a new array:

const result = []
for (let DCN in map) {
    result.push({
        DCN,
        value: Math.max(...map[DCN])
    })
}
Tracer69
  • 1,050
  • 1
  • 11
  • 26
0

reduce can do this nice and clean. the reduce() method executes a reducer function on each element of the array. the reducer function is the function which we will provide which will help maintain the maximum version number.

const arr = [
  {
    'DCN': '1234567',
    'Version': 1.0
  },
  {
    'DCN': '1234567',
    'Version': 2.0
  },
  {
    'DCN': '1234567',
    'Version': 3.0
  },
  {
    'DCN': '1234567',
    'Version': 4.0
  },
  {
    'DCN': '1234568',
    'Version': 1.0
  },
  {
    'DCN': '1234568',
    'Version': 2.0
  },
  {
    'DCN': '1234568',
    'Version': 3.0
  },
  {
    'DCN': '1234568',
    'Version': 4.0
  },
  {
    'DCN': '1234569',
    'Version': 3.0
  },
  {
    'DCN': '1234569',
    'Version': 4.0
  }
];

var result = Object.values(arr.reduce((r,o) => {
  if(o.DCN in r) {
    if(o.Version > r[o.DCN].Version)
      r[o.DCN] = Object.assign({},o);
  } else {
    r[o.DCN] = Object.assign({}, o);
  }
  return r;
},{}));

console.log(result);
Ran Turner
  • 14,906
  • 5
  • 47
  • 53