import { AsyncIterableX } from '../asynciterablex' ; import { toArray } from '../toarray' ; import { sorter as defaultSorter } from '../../util/sorter' ; import { UnaryFunction } from '../../interfaces' ; import { throwIfAborted } from '../../aborterror' ; export abstract class OrderedAsyncIterableBaseX < TSource > extends AsyncIterableX < TSource > { _source : AsyncIterable < TSource > ; constructor ( source ) { super ( ) ; this . _source = source ; } async * [ Symbol . asyncIterator ] ( signal ? ) { throwIfAborted ( signal ) ; const array = await toArray ( this . _source , signal ) ; const len = array . length ; const indices = new Array < number > ( len ) ; for ( let i = 0 ; i < len ; i ++ ) { indices [ i ] = i ; } indices . sort ( this . _getSorter ( array ) ) ; for ( const index of indices ) { yield array [ index ] ; } } thenBy < TKey > ( keySelector , comparer = defaultSorter ) { return new OrderedAsyncIterableX < TKey , TSource > ( this . _source , keySelector , comparer , false , this ) ; } thenByDescending < TKey > ( keySelector , comparer = defaultSorter ) { return new OrderedAsyncIterableX < TKey , TSource > ( this . _source , keySelector , comparer , true , this ) ; } abstract _getSorter ( elements , next ? ) ; } export class OrderedAsyncIterableX < TKey , TSource > extends OrderedAsyncIterableBaseX < TSource > { private _keySelector : ( item : TSource ) => TKey ; private _comparer : ( fst : TKey , snd : TKey ) => number ; private _descending : boolean ; private _parent ? : OrderedAsyncIterableBaseX < TSource > ; constructor ( source , keySelector , comparer , descending , parent ? ) { super ( source ) ; this . _keySelector = keySelector ; this . _comparer = comparer ; this . _descending = descending ; this . _parent = parent ; } _getSorter ( elements , next ? ) { const keys = elements . map ( this . _keySelector ) ; const comparer = this . _comparer ; const parent = this . _parent ; const descending = this . _descending ; const sorter = ( x , y ) : number => { const result = comparer ( keys [ x ] , keys [ y ] ) ; if ( result === 0 ) { return next ? next ( x , y ) : x - y ; } return descending ? - result : result ; } ; return parent ? parent . _getSorter ( elements , sorter ) : sorter ; } } template TKey template TSource param { ( item : TSource ) => TKey } keySelector param { ( fst : TKey , snd : TKey ) => number } comparer returns { UnaryFunction < AsyncIterable < TSource > , OrderedAsyncIterableX < TKey , TSource > > } export function orderBy < TKey , TSource > ( keySelector , comparer = defaultSorter ) { return function orderByOperatorFunction ( source ) { return new OrderedAsyncIterableX < TKey , TSource > ( source , keySelector , comparer , false ) ; } ; } template TKey template TSource param { ( item : TSource ) => TKey } keySelector param { ( fst : TKey , snd : TKey ) => number } comparer returns { UnaryFunction < AsyncIterable < TSource > , OrderedAsyncIterableX < TKey , TSource > > } export function orderByDescending < TKey , TSource > ( keySelector , comparer = defaultSorter ) { return function orderByDescendingOperatorFunction ( source ) { return new OrderedAsyncIterableX < TKey , TSource > ( source , keySelector , comparer , true ) ; } ; } template TKey template TSource param { ( item : TSource ) => TKey } keySelector param { ( fst : TKey , snd : TKey ) => number } comparer returns { UnaryFunction < AsyncIterable < TSource > , OrderedAsyncIterableX < TKey , TSource > > } export function thenBy < TKey , TSource > ( keySelector , comparer = defaultSorter ) { return function thenByOperatorFunction ( source ) { const orderSource = < OrderedAsyncIterableBaseX < TSource > > source ; return new OrderedAsyncIterableX < TKey , TSource > ( orderSource . _source , keySelector , comparer , false , orderSource ) ; } ; } template TKey template TSource param { ( item : TSource ) => TKey } keySelector param { ( fst : TKey , snd : TKey ) => number } comparer returns { UnaryFunction < AsyncIterable < TSource > , OrderedAsyncIterableX < TKey , TSource > > } export function thenByDescending < TKey , TSource > ( keySelector , comparer = defaultSorter ) { return function thenByDescendingOperatorFunction ( source ) { const orderSource = < OrderedAsyncIterableBaseX < TSource > > source ; return new OrderedAsyncIterableX < TKey , TSource > ( orderSource . _source , keySelector , comparer , true , orderSource ) ; } ; }