首页 > 解决方案 > 如何基于多个属性聚合和合并对象?

问题描述

我需要你的支持才能在 Ramda 中进行 groupby。

我有一个数据,我需要:

  1. 按服务类型对数据进行排序
  2. 将相同产品代码的产品分开
  3. 制作持续时间的 groupby
  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

标签: javascriptramda.js

解决方案


我将reduceBy用于此任务:

  • collect用于对持续时间进行分组
  • key用于识别一对唯一的服务类型和产品代码

值得注意的是,它collect做了一些重复,因为它一直在重新分配相同的服务类型和产品代码,但我认为它可以忽略不计。

// merge similar objects
const collect = (acc, obj) => ({
  serviceType: obj.serviceType.description,
  productCode: obj.productCode,
  duration: acc.duration.concat(obj.duration.months)
});

// key generating function used to group similar objects together
const key = obj => `${obj.serviceType.description}-${obj.productCode}`;

// transformation function
const transform = compose(values, reduceBy(collect, {duration:[]}, key));

console.log(

  transform(data)
  
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {compose, values, reduceBy} = R;</script>
<script>
const data = [
  { 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 }}];
</script>


推荐阅读