import { Observable } from '../Observable'; import { Subject } from '../Subject'; import { groupBy as higherOrder, GroupedObservable } from '../operators/groupBy'; export { GroupedObservable }; /* tslint:disable:max-line-length */ export function groupBy(this: Observable, keySelector: (value: T) => K): Observable>; export function groupBy(this: Observable, keySelector: (value: T) => K, elementSelector: void, durationSelector: (grouped: GroupedObservable) => Observable): Observable>; export function groupBy(this: Observable, keySelector: (value: T) => K, elementSelector?: (value: T) => R, durationSelector?: (grouped: GroupedObservable) => Observable): Observable>; export function groupBy(this: Observable, keySelector: (value: T) => K, elementSelector?: (value: T) => R, durationSelector?: (grouped: GroupedObservable) => Observable, subjectSelector?: () => Subject): Observable>; /* tslint:enable:max-line-length */ /** * Groups the items emitted by an Observable according to a specified criterion, * and emits these grouped items as `GroupedObservables`, one * {@link GroupedObservable} per group. * * * * @example Group objects by id and return as array * Observable.of({id: 1, name: 'aze1'}, * {id: 2, name: 'sf2'}, * {id: 2, name: 'dg2'}, * {id: 1, name: 'erg1'}, * {id: 1, name: 'df1'}, * {id: 2, name: 'sfqfb2'}, * {id: 3, name: 'qfs3'}, * {id: 2, name: 'qsgqsfg2'} * ) * .groupBy(p => p.id) * .flatMap( (group$) => group$.reduce((acc, cur) => [...acc, cur], [])) * .subscribe(p => console.log(p)); * * // displays: * // [ { id: 1, name: 'aze1' }, * // { id: 1, name: 'erg1' }, * // { id: 1, name: 'df1' } ] * // * // [ { id: 2, name: 'sf2' }, * // { id: 2, name: 'dg2' }, * // { id: 2, name: 'sfqfb2' }, * // { id: 2, name: 'qsgqsfg2' } ] * // * // [ { id: 3, name: 'qfs3' } ] * * @example Pivot data on the id field * Observable.of({id: 1, name: 'aze1'}, * {id: 2, name: 'sf2'}, * {id: 2, name: 'dg2'}, * {id: 1, name: 'erg1'}, * {id: 1, name: 'df1'}, * {id: 2, name: 'sfqfb2'}, * {id: 3, name: 'qfs1'}, * {id: 2, name: 'qsgqsfg2'} * ) * .groupBy(p => p.id, p => p.name) * .flatMap( (group$) => group$.reduce((acc, cur) => [...acc, cur], ["" + group$.key])) * .map(arr => ({'id': parseInt(arr[0]), 'values': arr.slice(1)})) * .subscribe(p => console.log(p)); * * // displays: * // { id: 1, values: [ 'aze1', 'erg1', 'df1' ] } * // { id: 2, values: [ 'sf2', 'dg2', 'sfqfb2', 'qsgqsfg2' ] } * // { id: 3, values: [ 'qfs1' ] } * * @param {function(value: T): K} keySelector A function that extracts the key * for each item. * @param {function(value: T): R} [elementSelector] A function that extracts the * return element for each item. * @param {function(grouped: GroupedObservable): Observable} [durationSelector] * A function that returns an Observable to determine how long each group should * exist. * @return {Observable>} An Observable that emits * GroupedObservables, each of which corresponds to a unique key value and each * of which emits those items from the source Observable that share that key * value. * @method groupBy * @owner Observable */ export function groupBy(this: Observable, keySelector: (value: T) => K, elementSelector?: ((value: T) => R) | void, durationSelector?: (grouped: GroupedObservable) => Observable, subjectSelector?: () => Subject): Observable> { return higherOrder(keySelector, elementSelector as any, durationSelector, subjectSelector)(this); }