如何基于多个属性聚合和合并对象? [英] How to aggregate and merge objects based on multiple properties?

查看:59
本文介绍了如何基于多个属性聚合和合并对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要你的支持才能在 Ramda 中创建一个 groupby.

I need your support to make a groupby in Ramda.

我有一个数据,我需要:

I have a data and I require:

  1. 按服务类型对数据进行排序
  2. 区分那些相同的产品代码
  3. 制作持续时间的分组
  4. 合并所有数据

数据:

[{
    'id': '1', 'serviceType': { 'description': 'GE' },
    'productCode': 'codeTwo', 'duration': { 'months': 24 }, 
  }, {
    'id': '2', 'serviceType': { 'description': 'GE' },
    'productCode': 'codeOne', 'duration': { 'months': 12 }
  }, {
    'id': '3', 'serviceType': { 'description': 'RF' },
    'productCode': 'codeOne', 'duration': { 'months': 24 }, 
  }, {
    'id': '4', 'serviceType': { 'description': 'RF' },
    'productCode': 'codeOne', 'duration': { 'months': 12 }, 
  }, {
    'id': '5', 'serviceType': { 'description': 'RF' },
    'productCode': 'codeOne', 'duration': { 'months': 36 }, 
  }, {
    'id': '6', 'serviceType': { 'description': 'GE' },
    'productCode': 'codeOne', 'duration': { 'months': 24 }
  }]

预期结果:

[{
  'serviceType': 'GE',
  'productCode': 'codeOne',
  'duration': [12,24]
}, {
  'serviceType': 'RF',
  'productCode': 'codeOne',
  'duration': [12,24,36]
}, {
  'serviceType': 'GE',
  'productCode': 'codeTwo',
  'duration': [24]
}]

错误测试:

data.map(item => {
  (item.serviceType === 'GE') ? listGE.push(item) : listRF.push(item)
  R.compose(
    R.values,
    R.map(R.head), 
    R.map(R.prop('duration')),
    R.groupBy(m => m.id !== id ? m.id : m.id) 
  )(listGE)
  console.log(listGE);
})

listGE

推荐答案

另一种方法如下所示:

const transform = pipe (
  groupBy (({serviceType: {description}, productCode}) => `${description},${productCode}`),
  values,
  map (applySpec ({
    serviceType: path ([0, 'serviceType', 'description']),
    productCode: path ([0, 'productCode']),
    duration: pipe (pluck ('duration'), pluck ('months'), sort (subtract))
  })),
  sortWith ([ascend (prop ('productCode')), ascend (prop ('serviceType'))])
)

const data = [{"duration": {"months": 24}, "id": "1", "productCode": "codeTwo", "serviceType": {"description": "GE"}}, {"duration": {"months": 12}, "id": "2", "productCode": "codeOne", "serviceType": {"description": "GE"}}, {"duration": {"months": 24}, "id": "3", "productCode": "codeOne", "serviceType": {"description": "RF"}}, {"duration": {"months": 12}, "id": "4", "productCode": "codeOne", "serviceType": {"description": "RF"}}, {"duration": {"months": 36}, "id": "5", "productCode": "codeOne", "serviceType": {"description": "RF"}}, {"duration": {"months": 24}, "id": "6", "productCode": "codeOne", "serviceType": {"description": "GE"}}]

console.log (
  transform (data)
)

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {pipe, groupBy, values, map, applySpec, path, pluck, sort, subtract, sortWith, ascend, prop} = R</script>

这首先通过调用groupByvalues 将所有具有相同服务类型描述和产品代码的值组合在一起.然后对于每个组,它调用 applySpec 并使用产生您请求的输出的规范.最后我们按照产品代码和服务类型对这些结果对象进行排序.

This first groups together all the values that have the same service type description and product code by calling groupBy and then values. Then for each group it calls applySpec with a specification that yields your requested output. And finally we sort these resulting objects by product code then service type.

我敢肯定,稍微考虑一下我们就可以使传递给 groupBy 的函数无点,但我发现这个版本可读,并且无法真正想象一个无点版本更具可读性.

I'm sure that with a little thought we could make the function passed to groupBy point-free, but I find this version readable, and can't really imagine a point-free version which is more readable.

我不确定我是更喜欢这种方法还是来自 customcommander 的方法,但它们一起帮助展示了可能的各种答案.

I'm not really sure whether I prefer this or the approach from customcommander, but together they help show the variety of answers possible.

这篇关于如何基于多个属性聚合和合并对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆