Reputation: 4303
I have an array of objects. I want to get the max out of the number attribute from the array:
[
{number: 1000, name: "Josh"},
{number: 2000, name: "Joker"},
{number: 3000, name: "Batman"}
]
I'm using this solution but I keep getting NAN
:
const max = arr.reduce((a, b) => Math.max(a.number, b.number));
My goal is to get the max and then store it in a variable
const x = { number: 3000, name: "Batman"}
How would I achieve it with reduce? It seems like it is only working with array of numbers.
Upvotes: 6
Views: 1441
Reputation: 111
In case you really want to use Math.max()
as a part of the reduce callback, here is a sample:
You can create a mock hash map for your options, and use Math.max() to select the right one.
Also, Remember put an initial -Inf object for the very first comparison.
[
{number: 1000, name: 'Josh'},
{number: 2000, name: 'Joker'},
{number: 3000, name: 'Batman'},
].reduce((max, current) => {
return {
[max.number]: max,
[current.number]: current,
}[Math.max(max.number, current.number)];
}, {number: -Infinity});
Upvotes: 0
Reputation: 164731
With Array.prototype.reduce
, you have to remember that the first argument passed to the callback is the accumulator. That is, the return value from the previous iteration.
Math.max
returns a Number
(or NaN
if the operands cannot be compared numerically) so on the second iteration, you will be trying to compare the number
property of a Number
which won't work.
As an alternative to reduce
, you might want to consider sorting the array. This could be beneficial if you want other properties like the smallest value.
// smallest to largest, use "b.number - a.number" to reverse
arr.sort((a, b) => a.number - b.number)
arr[0] // smallest
arr[arr.length - 1] // largest
Upvotes: 4
Reputation: 816272
Math.max
returns a number. After the first iteration, a
is a number, not an object, so a.number
returns undefined
.
When you pass a second argument to .reduce
, you can ensure that the accumulator is always a number. If you only want to get the max number, for completeness, here is another way to do that:
const max = arr.reduce((a, b) => Math.max(a, b.number), -Infinity);
I'd still rather go with @ntgwsth solution for more flexibility.
Upvotes: 2
Reputation: 2591
You had the right idea. Here's a solution that uses reduce
and keeps tabs on the highest-ranking object in the array:
var nameNum = [
{number: 1000, name: "Josh"},
{number: 2000, name: "Joker"},
{number: 3000, name: "Batman"}
];
console.log(nameNum.reduce(function(max,current){return current.number>max.number?current:max;},{number:-Infinity, name:""}));
Upvotes: 0
Reputation: 6223
Done by simple reduce,
var arr=[{"number":1000,"name":"Josh"},{"number":2000,"name":"Joker"},{"number":3000,"name":"Batman"}]
var x = arr.reduce((acc, i)=>(i.number > acc.number ? i : acc))
console.log(x)
Upvotes: 10