来自具有属性的对象数组的 lodash 新对象
lodash new object from array of objects with properties
所以我有很多人,有他们的名字和钱。
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'
}
]
我想使用 lodash 和链接 return 一个对象,其中包含最富有的人的姓名和金钱,即使该人在数组中有多个对象,也可以汇总金钱总额。
Return 对象应该看起来像这样,没有地址。
{
name: Markus,
money: 390
},
我心中的脚步
- 将数组中所有重复的人的钱加到新数组中。
- 找出最高货币价值。最大()?
- Return首富新对象
我是 lodash 和函数式编程的新手。 lodash 文档和链接在这个阶段对我来说没有多大意义,很多术语我不理解,比如 iteratee、guarded、identity...等
我可以使用哪些函数来实现这一点?
对我来说,一个简单的 reduce
就可以完成工作:
let richest = 0;
let richestName;
const peopleMoneyMap = people.reduce((map, current) => {
const { name, money } = current;
map[name] = (map[name] || 0) + money;
if (map[name] > richest) {
richest = map[name];
richestName = name;
}
return map;
}, {})
const result = {
name: richestName,
money: richest,
}
如果您登录 peopleMoneyMap
,您将获得:
{
"Andre Balopos": 220,
"Lisa Stewart": 250,
"Marcus Ericsson": 390,
}
按钱分组,映射组,并用 name
和每个组的 money
的总和创建一个对象,并使用 _.maxBy()
找到对象最大值 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"}]
const result = _(people)
.groupBy('name')
.map((group, name) => ({
name,
money: _.sumBy(group, 'money')
}))
.maxBy('money')
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous"></script>
使用常规 Lodash:
- 使用
_.groupBy()
根据名称收集值。这会产生一个像这样的对象:
{
"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
和 money
属性 折叠组。结果是:
{
"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
选择货币价值最高的对象。
这可以通过 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/lodash@4.17.21/lodash.min.js"></script>
也可以使用 Lodash FP 通过将函数组合成一系列操作来完成相同的操作:
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>
所以我有很多人,有他们的名字和钱。
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'
}
]
我想使用 lodash 和链接 return 一个对象,其中包含最富有的人的姓名和金钱,即使该人在数组中有多个对象,也可以汇总金钱总额。 Return 对象应该看起来像这样,没有地址。
{
name: Markus,
money: 390
},
我心中的脚步
- 将数组中所有重复的人的钱加到新数组中。
- 找出最高货币价值。最大()?
- Return首富新对象
我是 lodash 和函数式编程的新手。 lodash 文档和链接在这个阶段对我来说没有多大意义,很多术语我不理解,比如 iteratee、guarded、identity...等
我可以使用哪些函数来实现这一点?
对我来说,一个简单的 reduce
就可以完成工作:
let richest = 0;
let richestName;
const peopleMoneyMap = people.reduce((map, current) => {
const { name, money } = current;
map[name] = (map[name] || 0) + money;
if (map[name] > richest) {
richest = map[name];
richestName = name;
}
return map;
}, {})
const result = {
name: richestName,
money: richest,
}
如果您登录 peopleMoneyMap
,您将获得:
{
"Andre Balopos": 220,
"Lisa Stewart": 250,
"Marcus Ericsson": 390,
}
按钱分组,映射组,并用 name
和每个组的 money
的总和创建一个对象,并使用 _.maxBy()
找到对象最大值 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"}]
const result = _(people)
.groupBy('name')
.map((group, name) => ({
name,
money: _.sumBy(group, 'money')
}))
.maxBy('money')
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous"></script>
使用常规 Lodash:
- 使用
_.groupBy()
根据名称收集值。这会产生一个像这样的对象:
{
"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
和money
属性 折叠组。结果是:
{
"Marcus Ericsson": 390,
"Andre Balopos": 220,
"Lisa Stewart": 250
}
- 使用
_.entries()
to get key-value pairs and_.map()
them into objects withname
andmoney
properties using_.zipObject()
(Credit to Ori Drori):
[
{ name: "Marcus Ericsson", money: 390 },
{ name: "Andre Balopos", money: 220 },
{ name: "Lisa Stewart", money: 250 }
]
- 用
_.maxBy
选择货币价值最高的对象。
这可以通过 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/lodash@4.17.21/lodash.min.js"></script>
也可以使用 Lodash FP 通过将函数组合成一系列操作来完成相同的操作:
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>