[我尝试使用groupByMult
编写将Ramda函数groupBy应用于对象groupBys
的数组的函数input
:
function groupByMult(groupBys, input) { ... }
它应该返回一个嵌套对象,该对象具有groupBys[0]
的子属性,groupBys[1]
的孙子属性,groupBys[2]
的孙子属性等等。最后一个大子级属性的值是属于该组路径的对象的数组(请参见底部的expected
输出)。
我用一个例子来解释期望的行为:
我的输入是一个对象数组。在此示例中,所有对象都具有属性g1
,g2
和g3
。
const input = [
{ g1: 'g1a', g2: 'g2a', g3: true },
{ g1: 'g1b', g2: 'g2b', g3: 42 },
{ g1: 'g1a', g2: 'g2a', g3: 'text' },
{ g1: 'g1a', g2: 'g2a', g3: false },
{ g1: 'g1a', g2: 'g2b', g3: 0 },
{ g1: 'g1a', g2: 'g2b', g3: 1 },
{ g1: 'g1a', g2: 'g2b', g3: true },
];
在我的示例中,我的小组职能是:
const groupBys = [
R.prop('g1'),
R.prop('g2'),
R.compose(R.type, R.prop('g3'))
];
我这样叫groupByMult
const outpout = groupByMult(groupBys, input);
而且我希望output
等于expected
:
const expected = {
g1a: {
g2a: {
Boolean: [
{ g1: 'g1a', g2: 'g2a', g3: true },
{ g1: 'g1a', g2: 'g2a', g3: false },
],
String: [
{ g1: 'g1a', g2: 'g2a', g3: 'text' },
],
},
g2b: {
Number: [
{ g1: 'g1a', g2: 'g2b', g3: 0 },
{ g1: 'g1a', g2: 'g2b', g3: 1 },
],
Boolean: [
{ g1: 'g1a', g2: 'g2b', g3: true },
],
},
},
g1b: {
g2b: {
Number: [
{ g1: 'g1b', g2: 'g2b', g3: 42 },
]
},
},
}
output
或expected
分别具有g1a
的子属性g1b
,groupBys[0]
等,g2a
的孙子属性g2b
,groupBys[1]
等,孙子属性[C0 ],Boolean
或Number
的String
,它们具有属于此组路径的对象数组。例如,数组groupBys[2]
的所有对象看起来都像output.g1a.g2b.Boolean
,其中{ g1: 'g1a', g2: 'g2b', Boolean: <boolean> }
代表任何布尔值。
我如何实现<boolean>
以获取所描述的行为?
groupByMult
之后递归地映射结果对象值的函数来实现。R.groupBy
[此函数将使用一个分组函数列表和一个对象列表,并继续递归调用自身,直到没有更多分组函数为止。例如:
groupByMany = R.curry((fns, items) => R.isEmpty(fns) ? items : R.map(groupByMany(R.tail(fns)), R.groupBy(R.head(fns), items)));
结果类似:
input = [ { g1: 'g1a', g2: 'g2a', g3: 'g3a' }, { g1: 'g1b', g2: 'g2c', g3: 'g3d' }, { g1: 'g1c', g2: 'g2a', g3: 'g3b' }, { g1: 'g1a', g2: 'g2b', g3: 'g3a' }, { g1: 'g1a', g2: 'g2b', g3: 'g3b' } ]; groupByMany([R.prop('g1'), R.prop('g2'), R.prop('g3')], input);
{ "g1a": { "g2a": { "g3a": [{ "g1": "g1a", "g2": "g2a", "g3": "g3a" }] },
"g2b": { "g3a": [{ "g1": "g1a", "g2": "g2b", "g3": "g3a" }],
"g3b": [{ "g1": "g1a", "g2": "g2b", "g3": "g3b" }] } },
"g1b": { "g2c": { "g3d": [{ "g1": "g1b", "g2": "g2c", "g3": "g3d" }] } },
"g1c": { "g2a": { "g3b": [{ "g1": "g1c", "g2": "g2a", "g3": "g3b" }] } } }
基于这样的输入:
const groups = R.pipe( R.groupBy(R.prop('g1')), R.map(R.groupBy(R.prop('g2'))), R.map(R.map(R.groupBy(R.compose(R.type, R.prop('g3'))))) );
[[0]包裹列表中的每个功能没有困难。那只是一个[ R.prop('g1'), R.prop('g2'), R.compose(R.type, R.prop('g3')) ]
通话。但是,要为每个元素增加groupBy
的列表,还需要做一些工作。我不确定是否有比此递归map
助手更优雅或更有效的东西,但这就是我想出的:
map
您可以在
addMap
]上看到它的作用