![](/img/trans.png)
[英]Lodash: How to get unique values from an object array and then sort those objects by those unique values?
[英]Flatten an array of objects and get unique keys and values by a repeated date with Lodash?
我一直在和Lodash玩耍,并且没有接近一个不涉及很多额外循环和开销的解决方案。
data: [
{
name: "FirstResult", values: [
{
value: { NameCount: 1, OtherCount: 1 },
date: 2019-05-15T07:00:00+0000
},
{
value: { NameCount: 1 },
date: 2019-05-16T07:00:00+0000
}
]
},
{
name: "SecondResult",
values: [
{
value: { NameCount: 1 },
date: 2019-05-15T07:00:00+0000
},
{
value: { BuyCount: 2, SellCount: 1 },
date: 2019-05-16T07:00:00+0000
}
]
}
]
我想弄平它,并通过使用日期作为返回一些配置的键来组合和汇总:
[
{ date: 2019-05-15T07:00:00+0000, values: { NameCount: 2, OtherCount: 1 } },
{ date: 2019-05-16T07:00:00+0000, values: { NameCount: 1, BuyCount: 2, SellCount: 1 } }
]
甚至只是一个平面对象数组都可以,例如:
[
{ date: 2019-05-15T07:00:00+0000, NameCount: 2, OtherCount: 1 },
{ date: 2019-05-16T07:00:00+0000, NameCount: 1, BuyCount: 2, SellCount: 1 }
]
有没有人对如何使用Lodash或Vanilla解决方案做到这一点有任何想法?
您可以使用lodash的链来展平,按日期分组,然后将每个分组映射并合并到单个对象:
const fn = data => _(data) .flatMap('values') // flatten to array of objects .groupBy(o => o.date.toISOString()) // group by the iso representation .map(group => { // map the groups by merging, and converting to require format const { date, value } = _.mergeWith({}, ...group, (objValue, srcValue) => _.isNumber(objValue) ? objValue + srcValue : undefined // combine numeric values ) return { date, ...value, } }) .value() const data = [{"name":"FirstResult","values":[{"value":{"NameCount":1,"OtherCount":1},"date": new Date("2019-05-15T07:00:00.000Z")},{"value":{"NameCount":1},"date": new Date("2019-05-16T07:00:00.000Z")}]},{"name":"SecondResult","values":[{"value":{"NameCount":1},"date":new Date("2019-05-15T07:00:00.000Z")},{"value":{"BuyCount":2,"SellCount":1},"date": new Date("2019-05-16T07:00:00.000Z")}]}] const result = fn(data) console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
或者,您可以使用_.flow()
生成函数( 我在这里使用lodash / fp ):
const { flow, flatMap, groupBy, map, mergeAllWith, cond, isNumber, add } = _ const fn = flow( flatMap('values'), // flatten to array of objects groupBy(o => o.date.toISOString()), // group by the iso representation map(mergeAllWith(cond([[isNumber, add]]))), // combine numeric values map(({ date, value }) => ({ date, ...value })) // format the objects ) const data = [{"name":"FirstResult","values":[{"value":{"NameCount":1,"OtherCount":1},"date": new Date("2019-05-15T07:00:00.000Z")},{"value":{"NameCount":1},"date": new Date("2019-05-16T07:00:00.000Z")}]},{"name":"SecondResult","values":[{"value":{"NameCount":1},"date":new Date("2019-05-15T07:00:00.000Z")},{"value":{"BuyCount":2,"SellCount":1},"date": new Date("2019-05-16T07:00:00.000Z")}]}] const result = fn(data) console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
这是基于Array.reduce和Array.forEach作为对象键的纯ES6解决方案:
const data = [{"name":"FirstResult","values":[{"value":{"NameCount":1,"OtherCount":1},"date": new Date("2019-05-15T07:00:00.000Z")},{"value":{"NameCount":1},"date": new Date("2019-05-16T07:00:00.000Z")}]},{"name":"SecondResult","values":[{"value":{"NameCount":1},"date":new Date("2019-05-15T07:00:00.000Z")},{"value":{"BuyCount":2,"SellCount":1},"date": new Date("2019-05-16T07:00:00.000Z")}]}] let result = data.reduce((r, { values }) => { values.forEach(({ value, date }) => { let keys = Object.keys(value), d = date.toISOString() r[d] = r[d] || Object.assign({}, ...keys.map(x => ({ date: d, [x]: 0 }))) keys.forEach(k => r[d][k] = (r[d][k] || 0) + value[k]) }) return r }, {}) console.log(Object.values(result))
主要思想是对值对象的键进行白色迭代,并在按日期分组时用它们组成一个对象。 然后last forEach
只是对每个结果对象的值求和。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.