如何基于多个属性聚合和合并对象? [英] How to aggregate and merge objects based on multiple properties?
问题描述
我需要你的支持才能在 Ramda 中创建一个 groupby.
I need your support to make a groupby in Ramda.
我有一个数据,我需要:
I have a data and I require:
- 按服务类型对数据进行排序
- 区分那些相同的产品代码
- 制作持续时间的分组
- 合并所有数据
数据:
[{
'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>
这首先通过调用groupBy
和values
将所有具有相同服务类型描述和产品代码的值组合在一起.然后对于每个组,它调用 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屋!