multi level groupby ramda js

2019-09-16 01:12发布

I have been trying to use group by at multiple levels so that the object is grouped by tag, folder and report keys. I was able to groupby at single level but could not proceed further.

const data = [{
  "_index": "search_index",
  "_type": "search_type",
  "_id": "Co5EFxnqeo9ruq",
  "_score": 1,
  "_source": {
    "admin_tags": [],
    "type": "human",
    "folder": "Feature Samples",
    "url_t": "url_tdata",
    "users": [
      128
    ],
    "agent_id": 2,
    "url": "url_data",
    "favorited_by": [20],
    "idx": 121,
    "path": "Report Samples//Feature Samples",
    "name": "Grouping and Sorting",
    "description": ""
  }
}];

const mapIndexed = R.addIndex(R.map);

const tg = mapIndexed((x, i) => ({
  "name": x._source.admin_tags[0] == undefined ? "Unclasified" : x._source.admin_tags[0],
  "idx": i,
  "folder": [{
    "name": x._source.folder,
    "idx": x._source.folder,
    "report": [{
      "agent_id": x._source.agent_id,
      "description": x._source.description,
      "favorited_by": x._source.favorited_by[0],
      "name": x._source.name,
      "idx": x._source.idx,
      "path": x._source.path,
      "type": x._source.type,
      "url": x._source.url,
      "url_t": x._source.url_t,
    }]
  }]
}), data);

const byTag = R.groupBy(data => data.name)
const tagged = byTag(tg);
console.log(tagged)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

This is the output I am trying to achieve with grouping at three levels and values of user_report_id, views always set to zero.

const output = {
  "message": "",
  "payload": [{
    "name": "Unclasified",
    "idx": 0,
    "folders": [{
      "idx": "Feature Samples",
      "name": "Feature Samples",
      "reports": [{
        "agent_id": 2,
        "description": "",
        "idx": 121,
        "is_fav": 20,
        "name": "Grouping and Sorting",
        "type": "human",
        "url": "url_data",
        "url_t": "url_tdata",
        "user_report_id": 0,
        "views": 0,
        "report_id": '2sdfsd'
      }]
    }]
  }]
}

1条回答
Luminary・发光体
2楼-- · 2019-09-16 02:08

There might be a better/built in solution, but you can use map to group the "inner lists" of your objects like so:

const data = [
  { letter: "a", number: 1, bool: true },
  { letter: "a", number: 2, bool: true },
  { letter: "a", number: 2, bool: false },
  { letter: "b", number: 1, bool: true },
  { letter: "b", number: 1, bool: false },
  { letter: "b", number: 1, bool: false },
  { letter: "c", number: 1, bool: true },
  { letter: "c", number: 2, bool: true },
  { letter: "c", number: 2, bool: false },
  { letter: "c", number: 2, bool: true },
];

const groupByLetterNumberBool = pipe(
  groupBy(prop("letter")),
  map(groupBy(prop("number"))),
  map(map(groupBy(prop("bool"))))
);

groupByLetterNumberBool(data);

Working example here.

查看更多
登录 后发表回答