UNPKG

data-collectors

Version:

A collection of composable reduction operations for arbitrary streams of values

112 lines (85 loc) 3.35 kB
export interface Supplier<T> { () : T; } export interface Accumulator<A, T> { ( container : A, item : T ) : void; } export interface Combinator<A> { ( first : A, second : A ) : A; } export interface Finisher<A, R> { ( container : A ) : R; } export interface Collector<T, A, R> { supply () : A; accumulate ( container : A, item : T ) : void; combine ( container1 : A, container2 : A ) : A; finish ( container : A ) : R; then <U> ( transformer : ( result : R ) => U ) : Collector<T, A, U>; apply ( iterable : Iterable<T> ) : R; } export class Collector<T, A, R> { static of<T, A, R> ( supplier : Supplier<A>, accumulator : Accumulator<A, T>, combinator : Combinator<A>, finisher : Finisher<A, R> ) : Collector<T, A, R>; static of<T, A> ( supplier : Supplier<A>, accumulator : Accumulator<A, T>, combinator : Combinator<A> ) : Collector<T, A, A>; static of<T, A, R> ( supplier : Supplier<A>, accumulator : Accumulator<A, T>, combinator : Combinator<A>, finisher ?: Finisher<A, R> ) { return new FunctionalCollector( supplier, accumulator, combinator, finisher || ( x => x as any ) ); } } export abstract class BaseCollector<T, A, R> implements Collector<T, A, R> { abstract supply () : A; abstract accumulate ( container : A, item : T ) : void; abstract combine ( container1 : A, container2 : A ) : A; abstract finish ( container : A ) : R; then <U> ( transformer : ( result : R ) => U ) : Collector<T, A, U> { return Collector.of( this.supply.bind( this ), this.accumulate.bind( this ), this.combine.bind( this ), ( result : A ) => transformer( this.finish( result ) ) ); } apply ( iterable : Iterable<T> ) : R { const container = this.supply(); for ( let item of iterable ) { this.accumulate( container, item ); } return this.finish( container ); } } export class FunctionalCollector<T, A, R> extends BaseCollector<T, A, R> implements Collector<T, A, R> { protected supplier : Supplier<A>; protected accumulator : Accumulator<A, T>; protected combinator : Combinator<A>; protected finisher : Finisher<A, R>; constructor ( supplier : Supplier<A>, accumulator : Accumulator<A, T>, combinator : Combinator<A>, finisher : Finisher<A, R> ) { super(); this.supplier = supplier; this.accumulator = accumulator; this.combinator = combinator; this.finisher = finisher; } supply () : A { return this.supplier(); } accumulate ( container : A, item : T ) : void { return this.accumulator( container, item ); } combine ( container1 : A, container2 : A ) : A { return this.combinator( container1, container2 ); } finish ( container : A ) : R { return this.finisher( container ); } } /** * Applies a given collector to the given iterator's items * * @param iterable * @param collector */ export function collect<T, R> ( iterable : Iterable<T>, collector : Collector<T, any, R> ) : R { return collector.apply( iterable ); }