使用Ramda对数组的项进行分组和转换

时间:2018-02-01 07:50:22

标签: javascript ramda.js

我需要按batchNumber对数组中的项目进行分组并对其值进行求和。

目前我正在使用ramda,但我可以分组,但不能转换结果。

请您使用ramda.js为我提供一个示例?

Live Example

const input = [
    {
        batchNumber: 'a',
        scrapAmount: 5
    },
    {
        batchNumber: 'a',
        scrapAmount: 10
    },
    {
        batchNumber: 'b',
        scrapAmount: 1
    },
    {
        batchNumber: 'b',
        scrapAmount: 2
    },
    {
        scrapAmount: 7
    },
    {
        scrapAmount: 3
    }
]

const byBatchNumber = R.groupBy((batch) => batch.batchNumber);


console.log(byBatchNumber(input))

/* result wanted

const output = [
    {
        batchNumber: 'a',
        scrapAmount: 15
    },
    {
        batchNumber: 'b',
        scrapAmount: 3
    },
    {
        batchNumber: undefined,
        scrapAmount: 10
    },
]

*/

2 个答案:

答案 0 :(得分:1)

groupWith()检查 batchNumber 是否与eqProps()相等。然后map()每个子数组,将mergeWithKey()应用于所有对象,add() scrapAmount 字段的值:



const { compose, groupWith, eqProps, map, apply, mergeWithKey, add } = R;

const input = [{"batchNumber":"a","scrapAmount":5},{"batchNumber":"a","scrapAmount":10},{"batchNumber":"b","scrapAmount":1},{"batchNumber":"b","scrapAmount":2},{"scrapAmount":7},{"scrapAmount":3}]

const byBatchNumber = compose(
  map(apply(mergeWithKey((k, l, r) => k === 'scrapAmount' ? add(l, r) : r))),
  groupWith(eqProps('batchNumber'))
)

console.log(byBatchNumber(input))

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

一个相当简单的版本如下:

const {pipe, groupBy, prop, map, pluck, sum} = R;

const input = [
    {batchNumber: 'a', scrapAmount: 5},
    {batchNumber: 'a', scrapAmount: 10},
    {batchNumber: 'b', scrapAmount: 1},
    {batchNumber: 'b', scrapAmount: 2},
    {scrapAmount: 7},
    {scrapAmount: 3}
]

const totalScrap = pipe(
  groupBy(prop('batchNumber')), 
  map(pluck('scrapAmount')), 
  map(sum)
)

console.log(totalScrap(input))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

首先请注意,这会将R.groupBy((batch) => batch.batchNumber)简化为R.groupBy(R.prop('batchNumber'));它的功能相同,只是表达得更简洁。

这是我想去的,因为我相信这是我通常做的工作最有用的输出格式,即:

{"a": 15, "b": 3, "undefined": 10}

但重读所需的输出,可能还需要两个步骤:

const {pipe, groupBy, prop, map, pluck, sum, toPairs, zipObj} = R;

const input = [
    {batchNumber: 'a', scrapAmount: 5},
    {batchNumber: 'a', scrapAmount: 10},
    {batchNumber: 'b', scrapAmount: 1},
    {batchNumber: 'b', scrapAmount: 2},
    {scrapAmount: 7},
    {scrapAmount: 3}
]

const totalScrap = pipe(
  groupBy(prop('batchNumber')), 
  map(pluck('scrapAmount')), 
  map(sum),
  toPairs,
  map(zipObj(['batchNumber', 'scrapAmount']))
)

console.log(totalScrap(input))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

这件事没有做的是生成一个batchNumber: undefined的项目,而是返回一个batchNumber: "undefined"(一个字符串)。虽然这可以修复,但这是一个丑陋的步骤,我看不到真正的收获。如果您的值为"undefined",则可能的解决方案会失败。如果这真的是一个显示阻止者,你显然可以在该管道的最后一步之前处理它们。