[英]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.