CuteMachine

How To Find The Maximum Of An Attribute Value In An Array Of JavaScript Objects

Finding the maximum value in an array of numbers is easy. Just use Math.max() and pass all the values in the array as arguments to the function call, and you are done.

const n = [1, 2, 3, 4, 3, 2, 1]
Math.max(...n)    // 4

If you have a vast array of numbers, this solution might not be suited, because you might run into errors like RangeError: too many function arguments. I tested this, and it was no problem to spread an array of 100000 values into the function call. Then I tried a million values and got the range error.

Therefore a better solution is not to rely on spreading but to use something like reduce. This solution will also work with a million values.

const aMillionValues = Array.from({ length: 1000000 }, (x, i) => {
  return i
});

const max = aMillionValues.reduce((acc, current) => acc > current ? acc: current, 1)
max    // 999999

Now imagine we do not have an array with numbers but say an array of point objects.

const points = [
  { x: 1, y: 1 },
  { x: 8, y: 2 },
  { x: 2, y: 3 },
  { x: 3, y: 4 },
]

How can we find the highest x position?

Finding The Maximum With Array.reduce()

To find the point furthest to the right, we need to look at all points and find the one with the highest x value.

We can achieve this with Array.reduce().

const points = [
  { x: 1, y: 1 },
  { x: 8, y: 2 },
  { x: 2, y: 3 },
  { x: 3, y: 4 },
]

const xMax = points.reduce((accObj, currentObj) =>
  accObj.x > currentObj.x ? accObj : currentObj, 1
).x
xMax   // 8

It is essential to pass an initial value to the reduce function. If you apply the function to an empty array, it will throw an error when you haven't provided an initial value.

Using Math.max() And Array Spreading To Find The Maximum

We can find the maximum x value with Math.max() and passing the values as arguments. To do this, we will use points.map() to create an array of all x values. And then spread the values of that array into the function call.

const points = [
  { x: 1, y: 1 },
  { x: 8, y: 2 },
  { x: 2, y: 3 },
  { x: 3, y: 4 },
]

const xMax = Math.max(...points.map(o => o.x), 0)
xMax    // 8

This solution has the before mentioned drawbacks of spreading a huge amount of values as arguments to a function call. But it also has another problem. Although we did get the maximum x value, we have no access to the point object itself.

Using maxBy() From Lodash To Find The Maximum

I'm (still) a massive fan of Lodash. And indeed, Lodash offers a great solution to our problem.

import maxBy from 'lodash/maxBy'

const points = [
  { x: 1, y: 1 },
  { x: 8, y: 2 },
  { x: 2, y: 3 },
  { x: 3, y: 4 },
]

const rightmost = maxBy(points, 'x')
rightmost      // { x: 8, y: 2 }
rightmost.x    // 8

The code is expressive and returns not only the maximum x value but also the point object itself.

Conclusion

I would refrain from spreading values to Math.max() and would either use the Array.reduce() solution or maxBy() from Lodash.

Posted on CuteMachine.

Jo's Profile ImageWritten by Jo who lives and works in Frankfurt building digital doodah. Stalk him on Twitter.

TOS • Privacy • Disclaimer