使用 Ramda 对数组的项目进行分组和转换
Using Ramda to group and transform items of an array
我需要按 batchNumber
对数组中的项目进行分组,然后对它们的值求和。
目前我正在使用ramda,但我可以分组但不能转换结果。
能否请您提供一个使用 ramda.js 的示例?
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
},
]
*/
您 groupWith()
by checking that the batchNumber is equal with eqProps()
. Then map()
each subarray, apply mergeWithKey()
to all objects, and 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>
一个相当简单的版本如下:
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
的项目,而不是 returns 一个带有 batchNumber: "undefined"
(字符串)的项目。虽然这可以修复,但它一个丑陋的步骤,我看不到真正的收获。如果您有一个值为 "undefined"
的解决方案,则可能会失败。如果这真的是一个阻碍,你显然可以在该管道的最后一步之前处理这些。
我需要按 batchNumber
对数组中的项目进行分组,然后对它们的值求和。
目前我正在使用ramda,但我可以分组但不能转换结果。
能否请您提供一个使用 ramda.js 的示例?
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
},
]
*/
您 groupWith()
by checking that the batchNumber is equal with eqProps()
. Then map()
each subarray, apply mergeWithKey()
to all objects, and 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>
一个相当简单的版本如下:
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
的项目,而不是 returns 一个带有 batchNumber: "undefined"
(字符串)的项目。虽然这可以修复,但它一个丑陋的步骤,我看不到真正的收获。如果您有一个值为 "undefined"
的解决方案,则可能会失败。如果这真的是一个阻碍,你显然可以在该管道的最后一步之前处理这些。