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

问题描述 投票:3回答:3

[我尝试使用groupByMult编写将Ramda函数groupBy应用于对象groupBys的数组的函数input

function groupByMult(groupBys, input) { ... }

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

我用一个例子来解释期望的行为:

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

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 },
      ]
    },
  },
}

outputexpected分别具有g1a的子属性g1bgroupBys[0]等,g2a的孙子属性g2bgroupBys[1]等,孙子属性[C0 ],BooleanNumberString,它们具有属于此组路径的对象数组。例如,数组groupBys[2]的所有对象看起来都像output.g1a.g2b.Boolean,其中{ g1: 'g1a', g2: 'g2b', Boolean: <boolean> }代表任何布尔值。

我如何实现<boolean>以获取所描述的行为?

javascript functional-programming ramda.js
3个回答
6
投票
这应该可以通过在应用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);


2
投票
在我看来,您想做的事,例如您的例子是这样的:

{ "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]上看到它的作用


1
投票
减少功能数组并累积映射的组成。对于嵌套的分组对象,我们再次使用map(map(fn),input)对值进行分组:
© www.soinside.com 2019 - 2024. All rights reserved.