Miguel Stevens
Miguel Stevens

Reputation: 9211

ES6 Find the maximum number of an array of objects

I have the following data

shots = [
    {id: 1, amount: 2},
    {id: 2, amount: 4}
]

Now I'm trying to get the object which has the highest amount

I've tried using reduce like follows

let highest = shots.reduce((max, shot) => {
    return shot.amount > max ? shot : max, 0
});

But I'm always getting the lowest number. Any idea what I might be missing?

Thank you.

Upvotes: 6

Views: 24045

Answers (7)

Nina Scholz
Nina Scholz

Reputation: 386654

You could check the amount property of both items and return the item with the greatest amount.

let highest = shots.reduce((a, b) => a.amount > b.amount ? a : b);

For same amount, you get the first object with the same amount only.

It does not work with an empty array.

If you like all objects with the same highest amount, you could reduce the array with with two conditions.

let highest = shots.reduce((r, o) => {
        if (!r || o.amount > r[0].amount) return [o];
        if (o.amount === r[0].amount) r.push(o);
        return r;
    }, undefined);

Upvotes: 1

scagood
scagood

Reputation: 782

There are two problems here, the first is that a reduce needs a return value. the second is you're comparing a number with an object.

Therefore, I think you need something like this:

// This will return the object with the highest amount.
let highest = shots.reduce((max, shot) => {
    return shot.amount >= max.amount ? shot : max;
}, {
    // The assumption here is that no amount is lower than a Double-precision float can go.
    amount: Number.MIN_SAFE_INTEGER
});

// So, we can convert the object to the amount like so:
highest = highest.amount;

Edit:

A clean short one liner would look something like so:

const highest = shots.sort((a, b) => b.amount - a.amount)[0]

Upvotes: 15

Cristian S.
Cristian S.

Reputation: 973

Cleaner 2 lines solution :)

const amounts = shots.map((a) => a.amount)
const highestAmount = Math.max(...amounts);

Update

Code above will return the highest amount. If you want to get the object that contains it, you will face the posibility that many objects contain the highest value. So you will need filter.

const highestShots = shots.filter(shot => shot.amount === highestAmount)

Upvotes: 18

Jonathan Deon
Jonathan Deon

Reputation: 46

You can use this code. It will simply return the highest amount.

Math.max.apply(Math,shots.map((shot)=>{return shot.amount;}));

Upvotes: 0

Rogier Slag
Rogier Slag

Reputation: 526

Sadly enough most answers here do not properly consider all cases

  1. The seed value is off
  2. The comparison is going between different types

To properly handle negative values, you would have to seed with -Infinity

Secondly compare the largest value of that point with the new value

You'd get the following:

highest = shots.reduce((max, current) => current.amount >= max.amount ? current : max, {amount: -Infinity})

You can test this with

shots = [
    {id: 1, amount: -2},
    {id: 2, amount: -4},
    {id: 3, amount: -4},
    {id: 4, amount: -5},
]
highest = shots.reduce((max, current) => current.amount >= max.amount ? current : max, {amount: -Infinity}) // Returns id 1, amount -2

shots = [
    {id: 1, amount: 2},
    {id: 2, amount: 4},
    {id: 3, amount: 4},
    {id: 4, amount: 5},
]
highest = shots.reduce((max, current) => current.amount > max.amount ? current : max, {amount: -Infinity}) // Returns id 4 amount 5

Note that if the array is empty, you will get a value of {amount: -Infinity} as a result, so you might want to handle the case where shots.length === 0 before the reduce

Upvotes: 2

Amin Fazlali
Amin Fazlali

Reputation: 1237

Try this:

Updated

let highest = shots.reduce((max, shot) => {
  return shot.amount > max.amount ? shot : max
}, {amount:0});

Upvotes: 2

gurvinder372
gurvinder372

Reputation: 68393

There are couple of mistakes

  • return shot.amount instead of shot
  • simply return the value after comparison

Finally

shots.reduce((max, shot) => 
    shot.amount > max ? shot.amount : max, 0);

Demo

var shots = [
    {id: 1, amount: 2},
    {id: 2, amount: 4}
];
var output = shots.reduce((max, shot) => 
    shot.amount > max ? shot.amount : max, 0);
console.log( output );

Edit

If the entire object has to be returned, then initializer should be an object with amount property

var shots = [
    {id: 1, amount: 2},
    {id: 2, amount: 4} ]; 
var output = shots.reduce((max, shot) => 
    shot.amount > max.amount ? shot : max , {amount:0}); 
console.log( output );

Upvotes: 0

Related Questions