-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgroupBy.ts
36 lines (33 loc) · 1.34 KB
/
groupBy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import { identity } from '../util/identity';
import { iteratee } from '../util/iteratee';
import { values } from '../object/values';
type PropertyName = string | number | symbol;
type IterateeShorthand<T> = PropertyName | [PropertyName, any] | Partial<T>;
type ValueIterator<T, R> = (value: T) => R;
type ValueIterateeCustom<T, R> = ValueIterator<T, R> | IterateeShorthand<T>;
function groupBy<T, R extends PropertyName>(collection: T[], predicate?: ValueIterateeCustom<T, R>): Record<R, T[]>;
function groupBy<R extends PropertyName>(
collection: string,
predicate?: ValueIterateeCustom<string, R>
): Record<R, string[]>;
function groupBy<K extends PropertyName, V, R extends PropertyName>(
collection: Record<K, V>,
predicate?: ValueIterateeCustom<V, R>
): Record<R, V>;
function groupBy<R extends PropertyName>(
collection: any,
predicate: ValueIterateeCustom<any, R> = identity
): Record<R, any> {
const iterativeFunc = iteratee(predicate);
const result: Record<PropertyName, any> = {};
values(collection).forEach((value) => {
const generated = iterativeFunc(value);
if (Object.prototype.hasOwnProperty.call(result, generated)) {
result[generated].push(value);
} else {
Object.assign(result, { [generated]: [value] });
}
});
return result;
}
export { groupBy };