{"action":"created","issue":{"url":"https://api.github.com/repos/ramda/ramda/issues/1598","labels_url":"https://api.github.com/repos/ramda/ramda/issues/1598/labels{/name}","comments_url":"https://api.github.com/repos/ramda/ramda/issues/1598/comments","events_url":"https://api.github.com/repos/ramda/ramda/issues/1598/events","html_url":"https://github.com/ramda/ramda/pull/1598","id":127053235,"number":1598,"title":"Add function reduceBy (a more general groupBy)","user":{"login":"jirutka","id":949228,"avatar_url":"https://avatars.githubusercontent.com/u/949228?v=3","gravatar_id":"","url":"https://api.github.com/users/jirutka","html_url":"https://github.com/jirutka","followers_url":"https://api.github.com/users/jirutka/followers","following_url":"https://api.github.com/users/jirutka/following{/other_user}","gists_url":"https://api.github.com/users/jirutka/gists{/gist_id}","starred_url":"https://api.github.com/users/jirutka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jirutka/subscriptions","organizations_url":"https://api.github.com/users/jirutka/orgs","repos_url":"https://api.github.com/users/jirutka/repos","events_url":"https://api.github.com/users/jirutka/events{/privacy}","received_events_url":"https://api.github.com/users/jirutka/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":15,"created_at":"2016-01-16T20:57:30Z","updated_at":"2016-01-24T02:15:46Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/ramda/ramda/pulls/1598","html_url":"https://github.com/ramda/ramda/pull/1598","diff_url":"https://github.com/ramda/ramda/pull/1598.diff","patch_url":"https://github.com/ramda/ramda/pull/1598.patch"},"body":"### Motivation\r\n\r\nI very often need to group elements of a list and immediately apply some transformation to the grouped sub-lists or their elements. It’s usually quite ineffective to do it in two steps (requires another loop with nested loop and intermediate arrays).\r\n\r\nI’m quite sure that it’s very common need so there _must be_ some “standard” name for such function. I’ve tried to find something in Haskell, but without success. Eventually I found a function named `reduceBy` which does what I need in these two libs:\r\n\r\n* [itertoolz.reduceby](http://toolz.readthedocs.org/en/latest/api.html#toolz.itertoolz.reduceby) (Python), \r\n* [CloudFlow.reduceBy](https://github.com/mbraceproject/MBrace.Core/blob/7de07474e7ed32adc90a66c93c6e8fa279577a14/src/MBrace.Flow/Combinators.fs#L646-L666) (F#).\r\n\r\n#### Example 1\r\n\r\n```js\r\nconst students = [\r\n  { name: 'Lucy', score: 92 },\r\n  { name: 'Drew', score: 85 },\r\n  // ...\r\n  { name: 'Bart' score: 62 },\r\n]\r\nconst grade = (n) => (n < 65) ? 'F' : (n < 70) ? 'D' : (n < 80) ? 'C' : (n < 90) ? 'B' : 'A'\r\nconst byGrade = R.pipe(R.prop('score'), grade)\r\n\r\n// A. Using R.groupBy and nested pair of R.map:\r\nconst namesByGrade = R.pipe(\r\n  R.groupBy(byGrade),\r\n  R.map(R.map(R.prop('name')))\r\n)\r\n\r\n// B. Using new R.reduceBy:\r\nconst namesByGrade = R.reduceBy(byGrade, (acc, stud) => acc.concat(stud.name), [])\r\n\r\nnamesByGrade(students)\r\n// {\r\n//   'A': ['Lucy'],\r\n//   'B': ['Drew'],\r\n//   // ...\r\n//   'F': ['Bart'],\r\n// }\r\n```\r\n\r\n#### Example 2\r\n\r\n```js\r\nconst tweets = [\r\n  { author: '@drboolean', text: 'Lorem ipsum', favs: 60 },\r\n  { author: '@dan_abramov', text: 'dolor sit amet', favs: 80 },\r\n  { author: '@drboolean', tex: 'consectetur', favs: 40 },\r\n  // ...\r\n]\r\n\r\n// A. Using R.groupBy, R.map and nested R.reduce:\r\nconst sumFavsByUser = R.pipe(\r\n  R.groupBy(R.prop('author')),\r\n  R.map(R.reduce((acc, tw) => acc + tw.favs))\r\n)\r\n\r\n// B. Using new R.reduceBy:\r\nconst sumFavsByUser = R.reduceBy(R.prop('author'), (acc, tw) => acc + tw.favs, 0)\r\n\r\nsumFavsByUser(tweets)\r\n// {\r\n//    '@drboolean': 100,\r\n//    '@dan_abramov': 80,\r\n// }\r\n```\r\n\r\n### Transducer?\r\n\r\nI’ve implemented also `_xreduceBy` transducer, but I’m not sure how to use it (and so how to test it). How can be `groupBy` used with `R.transduce` or `R.into`?\r\n"},"comment":{"url":"https://api.github.com/repos/ramda/ramda/issues/comments/174243686","html_url":"https://github.com/ramda/ramda/pull/1598#issuecomment-174243686","issue_url":"https://api.github.com/repos/ramda/ramda/issues/1598","id":174243686,"user":{"login":"davidchambers","id":210406,"avatar_url":"https://avatars.githubusercontent.com/u/210406?v=3","gravatar_id":"","url":"https://api.github.com/users/davidchambers","html_url":"https://github.com/davidchambers","followers_url":"https://api.github.com/users/davidchambers/followers","following_url":"https://api.github.com/users/davidchambers/following{/other_user}","gists_url":"https://api.github.com/users/davidchambers/gists{/gist_id}","starred_url":"https://api.github.com/users/davidchambers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidchambers/subscriptions","organizations_url":"https://api.github.com/users/davidchambers/orgs","repos_url":"https://api.github.com/users/davidchambers/repos","events_url":"https://api.github.com/users/davidchambers/events{/privacy}","received_events_url":"https://api.github.com/users/davidchambers/received_events","type":"User","site_admin":false},"created_at":"2016-01-24T02:15:46Z","updated_at":"2016-01-24T02:15:46Z","body":"We don't exactly operate by voting, but your views are certainly important to me, @kedashoe. I agree we need to keep an eye on the size of the library.\r\n"}}