Need to reduce an array of Objects to return the highest value of the same name.
Need the following,
[
{
name: 'a',
value: 20
},
{
name: 'a',
value: 80
},
{
name: 'b',
value: 90
},
{
name: 'b',
value: 50
}
]
To return
[
{
name: 'a',
value: 80
},
{
name: 'b',
value: 90
}
]
I have a solution, but it seems a little to much, wondering if there is a more straightforward way to achieve it?
Below is the solution I could think of:
var toReduce = [
{
'name': 'a',
'value': 20
},
{
'name': 'a',
'value': 80
},
{
'name': 'b',
'value': 90
},
{
'name': 'b',
'value': 50
}
];
function arrayReducer(arrayToReduce) {
// Created an object separating by name
let reduced = arrayToReduce.reduce((accumulator, currentValue) => {
(accumulator[currentValue.name] =
accumulator[currentValue.name] || []).push(currentValue);
return accumulator;
}, {});
// Reduce object to the highest value
for (let quotes of Object.keys(reduced)) {
reduced[quotes] = reduced[quotes].reduce(
(accumulator, currentValue) => {
return accumulator && accumulator.value > currentValue.value
? accumulator
: currentValue;
}
);
}
// return only object values
return Object.values(reduced);
}
console.log(arrayReducer(toReduce));
5
Answers
You can calculate the maximum during
reduce()
rather than in a separate loop.The easiest here is probably a simple loop:
Of course you can turn this into a single statement with
reduce()
and so on, but legibility will suffer.This might help. But it’s not in one Go.
Another option is to use
Map.groupBy()
to group each object byname
. Once grouped, you can iterate through the map, and for each group of objects grab the maximumvalue
(this is done usingArray.from()
on the Map with a mapping function below):The
keep
function below is a reusable way to reduce a list of items into a map by their keys, and compare their values using a comparator.For the
key
andvalue
options, you can pass an accessor (getter) or a index (field) to tell the function how to determine how to "get" the value from the item.