import { Collector } from "../collector"; export interface Comparator { ( a : T, b : T ) : number; } export function averaging () : Collector { return Collector.of( () => ( { sum: 0, count: 0 } ), ( state, item ) => { state.sum += item; state.count += 1; }, ( stateA, stateB ) => ( { sum: stateA.sum + stateB.sum, count: stateA.count + stateB.count } ), ( { sum, count } ) => count > 0 ? sum / count : count ); } export function sum () : Collector { return Collector.of( () => 0, ( state, item ) => state + item, ( stateA, stateB ) => stateA + stateB, ( state ) => state ); } export function bounds ( comparator : Comparator ) : Collector; export function bounds () : Collector; export function bounds ( comparator ?: Comparator ) : Collector { if ( !comparator ) comparator = ( a : any, b : any ) => a - b; const accumulator = ( state : [T, T], item : T ) => { if ( state[ 0 ] == null || comparator( state[ 0 ], item ) < 0 ) state[ 0 ] = item; if ( state[ 1 ] == null || comparator( state[ 1 ], item ) > 0 ) state[ 1 ] = item; }; return Collector.of( () => [null, null] as [T, T], accumulator, ( a, b ) => { accumulator( a, b[ 0 ] ); accumulator( a, b[ 1 ] ); return a; } ); } export function max ( comparator : Comparator ) : Collector; export function max () : Collector; export function max ( comparator ?: Comparator ) : Collector { return bounds( comparator ).then( b => b[ 1 ] ); } export function min ( comparator : Comparator ) : Collector; export function min () : Collector; export function min ( comparator ?: Comparator ) : Collector { return bounds( comparator ).then( b => b[ 0 ] ); }