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