UNPKG

4.22 kBPlain TextView Raw
1
2import { Observable, Subject } from 'rxjs';
3import { groupBy as higherOrder } from 'rxjs/operators';
4import { GroupedObservable } from 'rxjs/internal-compatibility';
5
6/* tslint:disable:max-line-length */
7export function groupBy<T, K>(this: Observable<T>, keySelector: (value: T) => K): Observable<GroupedObservable<K, T>>;
8export function groupBy<T, K>(this: Observable<T>, keySelector: (value: T) => K, elementSelector: void, durationSelector: (grouped: GroupedObservable<K, T>) => Observable<any>): Observable<GroupedObservable<K, T>>;
9export function groupBy<T, K, R>(this: Observable<T>, keySelector: (value: T) => K, elementSelector?: (value: T) => R, durationSelector?: (grouped: GroupedObservable<K, R>) => Observable<any>): Observable<GroupedObservable<K, R>>;
10export function groupBy<T, K, R>(this: Observable<T>, keySelector: (value: T) => K, elementSelector?: (value: T) => R, durationSelector?: (grouped: GroupedObservable<K, R>) => Observable<any>, subjectSelector?: () => Subject<R>): Observable<GroupedObservable<K, R>>;
11/* tslint:enable:max-line-length */
12
13/**
14 * Groups the items emitted by an Observable according to a specified criterion,
15 * and emits these grouped items as `GroupedObservables`, one
16 * {@link GroupedObservable} per group.
17 *
18 * <img src="./img/groupBy.png" width="100%">
19 *
20 * @example <caption>Group objects by id and return as array</caption>
21 * Observable.of<Obj>({id: 1, name: 'aze1'},
22 * {id: 2, name: 'sf2'},
23 * {id: 2, name: 'dg2'},
24 * {id: 1, name: 'erg1'},
25 * {id: 1, name: 'df1'},
26 * {id: 2, name: 'sfqfb2'},
27 * {id: 3, name: 'qfs3'},
28 * {id: 2, name: 'qsgqsfg2'}
29 * )
30 * .groupBy(p => p.id)
31 * .flatMap( (group$) => group$.reduce((acc, cur) => [...acc, cur], []))
32 * .subscribe(p => console.log(p));
33 *
34 * // displays:
35 * // [ { id: 1, name: 'aze1' },
36 * // { id: 1, name: 'erg1' },
37 * // { id: 1, name: 'df1' } ]
38 * //
39 * // [ { id: 2, name: 'sf2' },
40 * // { id: 2, name: 'dg2' },
41 * // { id: 2, name: 'sfqfb2' },
42 * // { id: 2, name: 'qsgqsfg2' } ]
43 * //
44 * // [ { id: 3, name: 'qfs3' } ]
45 *
46 * @example <caption>Pivot data on the id field</caption>
47 * Observable.of<Obj>({id: 1, name: 'aze1'},
48 * {id: 2, name: 'sf2'},
49 * {id: 2, name: 'dg2'},
50 * {id: 1, name: 'erg1'},
51 * {id: 1, name: 'df1'},
52 * {id: 2, name: 'sfqfb2'},
53 * {id: 3, name: 'qfs1'},
54 * {id: 2, name: 'qsgqsfg2'}
55 * )
56 * .groupBy(p => p.id, p => p.name)
57 * .flatMap( (group$) => group$.reduce((acc, cur) => [...acc, cur], ["" + group$.key]))
58 * .map(arr => ({'id': parseInt(arr[0]), 'values': arr.slice(1)}))
59 * .subscribe(p => console.log(p));
60 *
61 * // displays:
62 * // { id: 1, values: [ 'aze1', 'erg1', 'df1' ] }
63 * // { id: 2, values: [ 'sf2', 'dg2', 'sfqfb2', 'qsgqsfg2' ] }
64 * // { id: 3, values: [ 'qfs1' ] }
65 *
66 * @param {function(value: T): K} keySelector A function that extracts the key
67 * for each item.
68 * @param {function(value: T): R} [elementSelector] A function that extracts the
69 * return element for each item.
70 * @param {function(grouped: GroupedObservable<K,R>): Observable<any>} [durationSelector]
71 * A function that returns an Observable to determine how long each group should
72 * exist.
73 * @return {Observable<GroupedObservable<K,R>>} An Observable that emits
74 * GroupedObservables, each of which corresponds to a unique key value and each
75 * of which emits those items from the source Observable that share that key
76 * value.
77 * @method groupBy
78 * @owner Observable
79 */
80export function groupBy<T, K, R>(this: Observable<T>, keySelector: (value: T) => K,
81 elementSelector?: ((value: T) => R) | void,
82 durationSelector?: (grouped: GroupedObservable<K, R>) => Observable<any>,
83 subjectSelector?: () => Subject<R>): Observable<GroupedObservable<K, R>> {
84 return higherOrder(keySelector, elementSelector as any, durationSelector, subjectSelector)(this);
85}