简体   繁体   English

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

[英]Using Ramda to group and transform items of an array

I need to group items from an array by batchNumber and sum their values. 我需要按batchNumber将数组中的项目batchNumber并对其值求和。

Currently I am using ramda, but I am able to group but not to transform the result. 目前,我使用的是ramda,但我可以分组但不能转换结果。

Could you please provide me an example using ramda.js? 您能给我一个使用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
    },
]

*/

You groupWith() by checking that the batchNumber is equal with eqProps() . groupWith()通过检查batchNumber是平等eqProps() Then map() each subarray, apply mergeWithKey() to all objects, and add() the values of the scrapAmount field: 然后map()每个子mergeWithKey() ,将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> 

A fairly simple version would be the following: 一个相当简单的版本如下:

 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> 

Note first that this simplifies R.groupBy((batch) => batch.batchNumber) to R.groupBy(R.prop('batchNumber')) ; 首先请注意,这将R.groupBy((batch) => batch.batchNumber)简化为R.groupBy(R.prop('batchNumber')) it' the same functionality, just expressed more concisely. 它具有相同的功能,只是表达更为简洁。

This is as far as I would go, because I believe this to be the most helpful output format for the work I usually do, namely something like this: 这是我所能做的,因为我认为这是我通常所做的工作中最有用的输出格式,例如:

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

But rereading your required output, it might take two more steps: 但是,重新读取所需的输出后,可能需要再执行两个步骤:

 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> 

One thing this doesn't do is to generate an item with batchNumber: undefined , and instead returns one with batchNumber: "undefined" (a string.) While this could be fixed, it's an ugly step, and I don't see a real gain. 这不做的一件事是生成一个具有batchNumber: undefined的项,而是返回一个带有batchNumber: "undefined" (字符串)的项。虽然可以解决,但这是一个丑陋的步骤,而且我看不到真正的收益。 And likely solutions would then fail if you had one with a value of "undefined" . 如果您的解决方案的值为"undefined"那么可能的解决方案将失败。 If this is really a show-stopper, you could obviously process these before the last step in that pipeline. 如果这确实是一个阻止因素,那么您显然可以在该管道的最后一步之前进行处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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