How to get the element with the max value in a JavaScript array

Consider the following JavaScript array of objects. Each object represents a player in a gaming platform including a unique identifier (id), their name and the number of wins achieved.

const players = [{
  id: 1,
  name: "Leanne Graham",
  wins: 13,
}, {
  id: 2,
  name: "Ervin Howell",
  wins: 8,
}, {
  id: 3,
  name: "Clementine Bauch",
  wins: 19
}];

How do you find the player with the most wins?#

One notable trait of this array is that it is unsorted so we cannot simply grab the first element (or last, depending on sort direction). Instead we need an algorithm that compares the elements against each other and returns the element with the max wins value.

The Array.reduce is our friend here. If you haven't seen the function signature before, it reads a bit awkwardly:

arr.reduce(callback( accumulator, currentValue[, index[, array]] ) {
  // return result from executing something for accumulator or currentValue
}[, initialValue]);

Let's apply Array.reduce to our use case to find the max value element in our array.

const playerWithMostWins = players.reduce(
  (prev, current) => {
    return prev.wins > current.wins ? prev : current
  }
);

And if you need to change the logic to the player with the least wins (for the wall of shame?), it's the same function but just with a different comparison function:

const playerWithMostWins = players.reduce(
  (prev, current) => {
    // Changed the > to a <
    return prev.wins < current.wins ? prev : current
  }
);

Why not Array.find or Math.max?#

Array.find is a very useful function but only if you can determine whether or not you have the right item independently from other items in the array, e.g. finding the player named Leanne Graham:

const leanne = players.find(p => p.name === "Leanne Graham");

Math.max could be used if you only cared about the value instead of the item that holds the value, e.g. finding the max number of wins:

const mostWins = Math.max(...players.map((p) => p.wins), 0);

But keep in mind this is an O(2n) operation, so you would still be better off using Array.reduce:

const playerWithMostWins = players.reduce(
  (prev, current) => {
    // Changed the > to a <
    return prev.wins < current.wins ? prev : current
  }
);

const mostWins = playerWithMostWins.wins;

My general rule for when I need to reach for Array.reduce is if I am using comparison words in the question I am trying to ask. Common comparision words are most, least, max, lowest, newest, oldest, etc.

Conditional UI in React#

One common use case for me using this Array.reduce method is when I need to conditionally adjust React UI based on an element's relative values.

Back to our original example, once I know which player has the most wins, I can place this highly treasured trophy emoji 馃弳 next to their name!

And here is the full component code:

const players = [
  {
    id: 1,
    name: 'Leanne Graham',
    wins: 13,
  },
  {
    id: 2,
    name: 'Ervin Howell',
    wins: 8,
  },
  {
    id: 3,
    name: 'Clementine Bauch',
    wins: 19,
  },
];

const PlayerList = () => {
  const playerWithMostWins = players.reduce((prev, current) => {
    return prev.wins > current.wins ? prev : current;
  });

  return (
    <ul>
      {players.map((p) => {
        const isPlayerWithMostWins = playerWithMostWins.id === p.id;
        return (
          <li key={p.id}>
            {p.name} ({p.wins}) {isPlayerWithMostWins && '馃弳'}
          </li>
        );
      })}
    </ul>
  );
};

export default PlayerList;

So the next time you need a quick and easy way to find that array element with the most or least of something, I hope you will consider Array.reduce!

Further questions about Array.reduce? Find me on Twitter.

Join the Newsletter

I write about software development of all kinds (mostly front-end).

I won't send you spam. Unsubscribe at any time.