繁体   English   中英

用Lodash重复日期展平对象数组并获得唯一的键和值?

[英]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.reduceArray.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM