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'))
; 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. And likely solutions would then fail if you had one with a value of "undefined"
. If this is really a show-stopper, you could obviously process these before the last step in that pipeline.