Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

Commit

Permalink
feat(reduceBy): Add module reduceBy
Browse files Browse the repository at this point in the history
  • Loading branch information
adambrgmn committed Jan 16, 2018
1 parent a1b1e41 commit 5f46a10
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 13 deletions.
42 changes: 42 additions & 0 deletions src/__tests__/reduceBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable no-nested-ternary */
import reduceBy from '../reduceBy';

describe('Core.reduceBy', () => {
test('splits the list into groups according to the grouping function', () => {
const grade = score =>
score < 65
? 'F'
: score < 70 ? 'D' : score < 80 ? 'C' : score < 90 ? 'B' : 'A';

const students = [
{ name: 'Abby', score: 84 },
{ name: 'Brad', score: 73 },
{ name: 'Chris', score: 89 },
{ name: 'Dianne', score: 99 },
{ name: 'Eddy', score: 58 },
{ name: 'Fred', score: 67 },
{ name: 'Gillian', score: 91 },
{ name: 'Hannah', score: 78 },
{ name: 'Irene', score: 85 },
{ name: 'Jack', score: 69 },
];

const byGrade = student => grade(student.score || 0);
const collectNames = (acc, student) => acc.concat(student.name);

expect(reduceBy(collectNames, [], byGrade, students)).toEqual({
A: ['Dianne', 'Gillian'],
B: ['Abby', 'Chris', 'Irene'],
C: ['Brad', 'Hannah'],
D: ['Fred', 'Jack'],
F: ['Eddy'],
});
});

test('returns an empty object if given an empty array', () => {
const byType = obj => obj.type;
const sumValues = (acc, obj) => acc + obj.val;

expect(reduceBy(sumValues, 0, byType, [])).toEqual({});
});
});
16 changes: 3 additions & 13 deletions src/countBy.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import reduce from './reduce';
import prop from './prop';
import assoc from './assoc';
import reduceBy from './reduceBy';
import inc from './inc';

const countBy = (fn, list) =>
reduce(
(acc, item) => {
const key = fn(item);
const existingKey = prop(key, acc);
return assoc(key, existingKey ? existingKey + 1 : 1, acc);
},
{},
list,
);
const countBy = (keyFn, list) => reduceBy(inc, 0, keyFn, list);

export { countBy as default };
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import prepend from './prepend';
import product from './product';
import prop from './prop';
import reduce from './reduce';
import reduceBy from './reduceBy';
import reduceRight from './reduceRight';
import reverse from './reverse';
import slice from './slice';
Expand Down Expand Up @@ -102,6 +103,7 @@ export {
product,
prop,
reduce,
reduceBy,
reduceRight,
reverse,
slice,
Expand Down
16 changes: 16 additions & 0 deletions src/reduceBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import reduce from './reduce';
import has from './has';
import assoc from './assoc';

const reduceBy = (valFn, valAcc, keyFn, list) =>
reduce(
(acc, item) => {
const key = keyFn(item);
const val = valFn(has(key, acc) ? acc[key] : valAcc, item);
return assoc(key, val, acc);
},
{},
list,
);

export { reduceBy as default };

0 comments on commit 5f46a10

Please sign in to comment.