import { Grouping } from "../../sync/Grouping" ; import { IAsyncEnumerable , IAsyncEqualityComparer , IEqualityComparer , IGrouping , SelectorKeyType } from "../../types" ; import { BasicAsyncEnumerable } from "../BasicAsyncEnumerable" ; type GroupByAsyncFunc = { param source param keySelector returns < TSource , TKey extends SelectorKeyType > ( source , keySelector ) : IAsyncEnumerable < IGrouping < TKey , TSource > > ; param source param keySelector param comparer returns < TSource , TKey > ( source , keySelector , comparer ) : IAsyncEnumerable < IGrouping < TKey , TSource > > ; } ; export const groupByAsync = < TSource , TKey > ( source , keySelector , comparer ? ) : IAsyncEnumerable < IGrouping < any , TSource > > => { if ( comparer ) { return groupByAsync_0 < TSource , TKey > ( source , keySelector , comparer ) ; } else { return groupByAsync_0_Simple ( source , keySelector as ( x : TSource ) => Promise < any > ) ; } } ; const groupByAsync_0_Simple = < TSource , TKey extends SelectorKeyType > ( source , keySelector ) : IAsyncEnumerable < IGrouping < TKey , TSource > > => { async function * iterator ( ) { const keyMap = { } ; for await ( const value of source ) { const key = await keySelector ( value ) ; const grouping = keyMap [ key ] ; if ( grouping ) { grouping . push ( value ) ; } else { keyMap [ key ] = new Grouping < TKey , TSource > ( key , value ) ; } } for ( const value in keyMap ) { yield keyMap [ value ] ; } } return new BasicAsyncEnumerable ( iterator ) ; } ; const groupByAsync_0 = < TSource , TKey > ( source , keySelector , comparer ) : IAsyncEnumerable < IGrouping < TKey , TSource > > => { async function * generate ( ) { const keyMap = new Array < Grouping < TKey , TSource > > ( ) ; for await ( const value of source ) { const key = await keySelector ( value ) ; let found = false ; for ( let i = 0 ; i < keyMap . length ; i ++ ) { const group = keyMap [ i ] ; if ( await comparer ( group . key , key ) === true ) { group . push ( value ) ; found = true ; break ; } } if ( found === false ) { keyMap . push ( new Grouping < TKey , TSource > ( key , value ) ) ; } } for ( const keyValue of keyMap ) { yield keyValue ; } } return new BasicAsyncEnumerable ( generate ) ; } ;