So I have an array of people, with their names and money.
const people = [
{
name: 'Marcus Ericsson',
money: 150,
address: 'UK, Briston 5555'
},
{
name: 'Marcus Ericsson',
money: 240,
address: 'UK, Briston 5555'
},
{
name: 'Andre Balopos',
money: 130,
address: 'UK, Swansea 4321'
},
{
name: 'Lisa Stewart',
money: 250,
address: 'UK, Swansea 7654'
},
{
name: 'Andre Balopos',
money: 90,
address: 'UK, Swansea 4321'
}
]
I want, using lodash and chaining, to return an object with the name and money of richest person even if that person has multiple objects in the array, summarizing the total amount of money. Return object should look something like this, without address.
{
name: Markus,
money: 390
},
The steps in my mind
I'm new to lodash and functional programming. lodash documentation and chaining doesn't make much sense to me at this stage, lots of terminology I don't understand like iteratee, guarded, identity...etc
Which functions can I use to achieve this?
Using regular Lodash:
_.groupBy()
to collect values together based on name. This results in an object like:{
"Marcus Ericsson": [
{ name: "Marcus Ericsson", money: 150, address: "UK, Briston 5555" },
{ name: "Marcus Ericsson", money: 240, address: "UK, Briston 5555" }
],
"Andre Balopos": [
{ name: "Andre Balopos", money: 130, address: "UK, Swansea 4321" },
{ name: "Andre Balopos", money: 90, address: "UK, Swansea 4321" }
],
"Lisa Stewart": [
{ name: "Lisa Stewart", money: 250, address: "UK, Swansea 7654" }
]
}
_.mapValues()
and _.sumBy
the money
property. Result is:{
"Marcus Ericsson": 390,
"Andre Balopos": 220,
"Lisa Stewart": 250
}
_.entries()
to get key-value pairs and _.map()
them into objects with name
and money
properties using _.zipObject()
(Credit to Ori Drori):[
{ name: "Marcus Ericsson", money: 390 },
{ name: "Andre Balopos", money: 220 },
{ name: "Lisa Stewart", money: 250 }
]
_.maxBy
.This can be achieved with implicit chaining:
const people = [ { name: 'Marcus Ericsson', money: 150, address: 'UK, Briston 5555' }, { name: 'Marcus Ericsson', money: 240, address: 'UK, Briston 5555' }, { name: 'Andre Balopos', money: 130, address: 'UK, Swansea 4321' }, { name: 'Lisa Stewart', money: 250, address: 'UK, Swansea 7654' }, { name: 'Andre Balopos', money: 90, address: 'UK, Swansea 4321' } ]
const result = _(people)
.groupBy("name") // 1. Group
.mapValues(arr => _.sumBy(arr, "money")) // 2. Collapse the groups
.entries() // 3. Get entries...
.map(values =>
_.zipObject(["name", "money"], values) // 3. ...and convert
)
.maxBy("money"); // 4. Get max
console.log(result);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
The same can also be done using Lodash FP by composing functions into a chain of operations:
const { entries, flow, groupBy, map, mapValues, maxBy, sumBy, zipObject } = _;
const people = [ { name: 'Marcus Ericsson', money: 150, address: 'UK, Briston 5555' }, { name: 'Marcus Ericsson', money: 240, address: 'UK, Briston 5555' }, { name: 'Andre Balopos', money: 130, address: 'UK, Swansea 4321' }, { name: 'Lisa Stewart', money: 250, address: 'UK, Swansea 7654' }, { name: 'Andre Balopos', money: 90, address: 'UK, Swansea 4321' } ];
const pipeline = flow(
groupBy("name"),
mapValues(sumBy("money")),
entries,
map(zipObject(["name", "money"])),
maxBy("money")
);
const result = pipeline(people);
console.log(result);
<script src="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)"></script>