由几个groupBy函数嵌套的对象组对

mai*_*mic 3 javascript functional-programming ramda.js

我试着写一个函数groupByMult使用Ramda应用于几个GROUPBY功能groupBys到对象的数组input:

function groupByMult(groupBys, input) { ... }
Run Code Online (Sandbox Code Playgroud)

它应该返回一个嵌套对象,该对象具有子属性groupBys[0],孙子属性groupBys[1],孙子属性groupBys[2]等等.最后一个grand子属性的值是属于该组路径的对象数组(请参阅expected底部的输出).

我用一个例子解释了所需的行为:

我的输入是一个对象数组.在此示例中,所有对象都具有属性g1,g2g3.

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 },
];
Run Code Online (Sandbox Code Playgroud)

在我的例子中,我的组功能是:

const groupBys = [
  R.prop('g1'),
  R.prop('g2'),
  R.compose(R.type, R.prop('g3'))
];
Run Code Online (Sandbox Code Playgroud)

我把groupByMult这样的

const outpout = groupByMult(groupBys, input);
Run Code Online (Sandbox Code Playgroud)

而且我期望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 },
      ]
    },
  },
}
Run Code Online (Sandbox Code Playgroud)

output或分别expected具有子属性g1a,g1b,的等groupBys[0],孙子女性g2a,g2b,的等groupBys[1],大孙子性质Boolean,NumberStringgroupBys[2],其具有属于该组路径中的物体的阵列.例如,该阵列的所有对象output.g1a.g2b.Boolean的样子{ g1: 'g1a', g2: 'g2b', Boolean: <boolean> },其中<boolean>表示任何布尔值.

如何实现groupByMult以获得所描述的行为?

Sco*_*her 6

这应该可以通过在应用后递归映射结果对象值的函数来实现R.groupBy.

groupByMany = R.curry((fns, items) => 
  R.isEmpty(fns) ? items
                 : R.map(groupByMany(R.tail(fns)),
                         R.groupBy(R.head(fns), items)));
Run Code Online (Sandbox Code Playgroud)

此函数将获取分组函数列表以及对象列表,并继续递归调用自身,直到没有其他函数要分组.

例如:

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);
Run Code Online (Sandbox Code Playgroud)

结果如下:

{ "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" }] } } }
Run Code Online (Sandbox Code Playgroud)