import { Arity1, curry } from '@typed/lambda' /** * Converts a list of values into groups keyed by passed in function. * @param f :: a -> b * @param list :: [a] * @returns { [key: B]: A } */ export const groupBy = curry(__groupBy) as { (f: Arity1, list: ReadonlyArray): Record (f: Arity1): (list: ReadonlyArray) => Record } function __groupBy( f: Arity1, list: ReadonlyArray, ): Record { return list.reduce(groupByReducer(f), {} as Record) } function groupByReducer(f: Arity1) { return (acc: Record, x: A) => { const key = f(x) if (!acc[key]) { acc[key] = [x] } else { acc[key].push(x) } return acc } }