import { AsyncIterableX } from '../asynciterablex' ; import { identityAsync } from '../../util/identity' ; import { createGrouping } from './_grouping' ; import { OperatorAsyncFunction } from '../../interfaces' ; import { throwIfAborted } from '../../aborterror' ; export class GroupedAsyncIterable < TKey , TValue > extends AsyncIterableX < TValue > { public readonly key : TKey ; private _source : Iterable < TValue > ; constructor ( key , source ) { super ( ) ; this . key = key ; this . _source = source ; } async * [ Symbol . asyncIterator ] ( signal ? ) { throwIfAborted ( signal ) ; for ( const item of this . _source ) { yield item ; } } } export class GroupByAsyncIterable < TSource , TKey , TValue > extends AsyncIterableX < GroupedAsyncIterable < TKey , TValue > > { private _source : AsyncIterable < TSource > ; private _keySelector : ( value : TSource , signal ? : AbortSignal ) => TKey | Promise < TKey > ; private _elementSelector : ( value : TSource , signal ? : AbortSignal ) => TValue | Promise < TValue > ; constructor ( source , keySelector , elementSelector ) { super ( ) ; this . _source = source ; this . _keySelector = keySelector ; this . _elementSelector = elementSelector ; } async * [ Symbol . asyncIterator ] ( signal ? ) { throwIfAborted ( signal ) ; const map = await createGrouping ( this . _source , this . _keySelector , this . _elementSelector , signal ) ; for ( const [ key , values ] of map ) { yield new GroupedAsyncIterable < TKey , TValue > ( key , values ) ; } } } export function groupBy < TSource , TKey > ( keySelector ) ; export function groupBy < TSource , TKey , TValue > ( keySelector , elementSelector ? ) ; template TSource template TKey template TValue param { ( ( value : TSource , signal ? : AbortSignal ) => TKey | Promise < TKey > ) } keySelector param { ( ( value : TSource , signal ? : AbortSignal * ) => TValue | Promise < TValue > ) } elementSelector returns { OperatorAsyncFunction < TSource , TResult > } export function groupBy < TSource , TKey , TValue > ( keySelector , elementSelector = identityAsync ) { return function groupByOperatorFunction ( source ) : AsyncIterableX < GroupedAsyncIterable < TKey , TValue > > { return new GroupByAsyncIterable < TSource , TKey , TValue > ( source , keySelector , elementSelector ) ; } ; }