1 |
|
2 | import { Observable, Subject } from 'rxjs';
|
3 | import { groupBy as higherOrder } from 'rxjs/operators';
|
4 | import { GroupedObservable } from 'rxjs/internal-compatibility';
|
5 |
|
6 | /* tslint:disable:max-line-length */
|
7 | export function groupBy<T, K>(this: Observable<T>, keySelector: (value: T) => K): Observable<GroupedObservable<K, T>>;
|
8 | export function groupBy<T, K>(this: Observable<T>, keySelector: (value: T) => K, elementSelector: void, durationSelector: (grouped: GroupedObservable<K, T>) => Observable<any>): Observable<GroupedObservable<K, T>>;
|
9 | export 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>>;
|
10 | export 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 | */
|
80 | export 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 | }
|