data-collectors
Version:
A collection of composable reduction operations for arbitrary streams of values
60 lines (51 loc) • 2.13 kB
text/typescript
import { Collector } from "../collector";
export interface Comparator<T> {
( a : T, b : T ) : number;
}
export function averaging () : Collector<number, any, number> {
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<number, any, number> {
return Collector.of(
() => 0,
( state, item ) => state + item,
( stateA, stateB ) => stateA + stateB,
( state ) => state
);
}
export function bounds<T> ( comparator : Comparator<T> ) : Collector<T, any, [T, T]>;
export function bounds () : Collector<number, any, [number, number]>;
export function bounds<T> ( comparator ?: Comparator<T> ) : Collector<T, any, [T, T]> {
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<T> ( comparator : Comparator<T> ) : Collector<T, any, T>;
export function max () : Collector<number, any, number>;
export function max<T> ( comparator ?: Comparator<T> ) : Collector<T, any, T> {
return bounds( comparator ).then( b => b[ 1 ] );
}
export function min<T> ( comparator : Comparator<T> ) : Collector<T, any, T>;
export function min () : Collector<number, any, number>;
export function min<T> ( comparator ?: Comparator<T> ) : Collector<T, any, T> {
return bounds( comparator ).then( b => b[ 0 ] );
}