UNPKG

sintexplicabo

Version:
264 lines (222 loc) 8.04 kB
import {ArrayList} from "./List"; import {Predication} from "./Predication"; import { array, ArrayStream, ascii, asyncStreamLambdaTo, comparator, lambdaType, MapType, objectStream, OptionalMapInterface, predication, StreamAble, streamLambda, streamLambdaK } from "./Interface"; import {Optional} from "./Optional"; import {Iterator, ListIterator} from "./Iterator"; import {RuntimeException} from "./Exception"; import {Collection} from "./Collection"; /*** * */ export class Stream<T> implements ArrayStream<T>,OptionalMapInterface<T,Stream<T>>{ private readonly list : array<T>= null; private findLimit : Number = null; constructor( value : array<T> = null ) { this.list = value; } /*** * * @param callback */ public each( callback : streamLambda<T> ): Stream<T> { let tmp : string|number, key : ascii; for( tmp in this.list ){ key = isNaN(parseInt(tmp))?tmp:parseInt(tmp); let valor : T = this.list[tmp]; if(typeof this.list[tmp]!=="function") callback(valor,key); } return this; } /** * * @param callback */ public mapTo<U>( callback : lambdaType<T,U> ): Stream<U> { let out : array<U> = [], i = 0; this.each((value,key)=>out[i++]=callback.call(this,value,key)); out = out.length>0?out:null; return new Stream<U>(out); } /** * @alpha * @test * @param callback */ public async asyncMapTo<U>( callback : asyncStreamLambdaTo<T,U> ): Promise<Stream<U>> { let out : array<U> = [], i = 0; let itr : Iterator<T> =this.iterator(); while( itr.hasNext() ){ out[i]= await callback.call(this,itr.next(),i); i++; } return new Stream<U>(out.length>0?out:null); } /*** * * @param callback */ public map( callback : streamLambda<T> ): Stream<T> {return this.mapTo<T>(callback);} /** * * @param callback */ public mapToInt( callback : streamLambda<T> ) : Stream<Number>{return this.mapTo<Number>(callback);} /*** * * @param callback */ public filter( callback : predication<T> ): Stream<T> { let out : array<T> = [], i : number = 0; this.each((value,key)=>{ let state : boolean, keyInt : number = 0; if( callback instanceof Predication ){ state = callback.test(value); }else state = callback.call(null,value,key); if((state && this.findLimit===null)||(state&&(this.findLimit>0&&out.length<this.findLimit))){ out[i++] = value; } }); return new Stream<T>( out ); } /*** * * @param limit */ public limit( limit : Number = null ): Stream<T> { this.findLimit = limit; return this; } public findFirst( ) : Optional<T> { let out : T = this.list[0]; return new Optional<T>(this.list[0]===undefined?null:out); } public findAny( ) : Optional<T> { let out : T = this.list[Math.floor(Math.random()*(this.list.length-1))]; return new Optional<T>(out===undefined?out:null); } public allMatch( callback : predication<T> = (()=> void 0) ): boolean { return this.filter(callback).count()===this.count(); } public anyMatch( callback : predication<T> = (()=> void 0) ): boolean { return this.filter(callback).count()>0; } public noneMatch( callback : predication<T> = (()=> void 0) ): boolean { return !this.anyMatch(callback); } public hasPeer(): boolean { return this.anyMatch( <T>(value,key)=> value%2===0 ); } public count(): number { return this.list.length; } public sum( ) : Optional<Number> { let sum : Number = 0; this.mapToInt(v=>v).each(value=>sum= parseInt(String(value))); return new Optional<Number>(sum); } public min(): Optional<Number> { let min : number = Number.MIN_VALUE; this.mapToInt(v=>v).each(value=>{ min = parseInt(String(value<min?value:min)) }); return new Optional<Number>(min); } public max() : Optional<Number> { let max : number = Number.MAX_VALUE; this.mapToInt(v=>v).each(value=>max = parseInt(String(value>max?value:max))); return new Optional<Number>(max); } public sorted( compareFn: (a: T, b: T) => number ) : Stream<T> { return new Stream<T>(this.list.sort(compareFn)); } public sort( comparatorFn: comparator<T>):Stream<T>{ Collection.sortA<T>(this.getList(),comparatorFn); return this; } public getList( ) : ArrayList<T> {return ArrayList.of<T>(this.list);} public toArray() : array<T> {return this.list;} public iterator(): Iterator<T> {return new Iterator<T>(this.list);} public listIterator(): ListIterator<T> { return new ListIterator<T>(this.list); } public static of<T>( list : array<T> ): Stream<T>{return new Stream(list);} } /*** * */ export abstract class AbstractObjectStream<K extends string|number,V> implements objectStream<K,V>{ private readonly list : MapType<K,V> = null; private findLimit : Number = null; protected constructor( value : MapType<K,V> ) { this.list = value; } public each(callback: streamLambdaK<V,K> ): objectStream<K, V> { let tmp : any,ret : any; try{for(tmp in this.list)if((ret = callback(this.list[tmp],tmp)))break;}catch (e) { throw new RuntimeException(e); } return new ObjectStream(ret); } public filter(predicate: predication<V> = (()=> void 0) ): ObjectStream<K, V> { let out : MapType<K, V> = <any>{}, i : number = 0; this.each((value,key)=>{ let state : boolean, keyInt : number = 0; if( predicate instanceof Predication ){ state = predicate.test(value); }else state = predicate.call(null,value,key); if((state && this.findLimit===null)||(state&&(this.findLimit>0&&i<this.findLimit))){ out[key] = value; i++; } }); return new ObjectStream<K,V>( out ); } public mapTo<U>(callback: streamLambdaK<U,K> ): StreamAble<K,U>{ let out : any = {}; this.each((value,key)=>out[key]=callback.call(this,value,key)); out = out.length>0?out:null; return new ObjectStream<K,U>(out); } public map( callback: streamLambdaK<V,K> ) : StreamAble<K, V>{return this.mapTo<V>(callback);} public findAny(): Optional<V> { let out : V = null, i: number= 0, rand :number = Math.floor(Math.random()*(this.count()-1)); this.each(value=>{ if(rand===i)return out=value; i++; }); return new Optional<V>(out); } public findFirst(): Optional<V> { let out : V = null; this.each(value=>out=value); return new Optional<V>(out); } public limit( limit : number): ObjectStream<K, V> { this.findLimit = limit; return this; } public noneMatch(callback : predication<V> ): boolean {return !this.anyMatch(callback);} public allMatch( callback: predication<V> ): boolean {return this.filter(callback).count()===this.count();} public anyMatch(callback: predication<V> ): boolean {return this.filter(callback).count()>0;} public count(): number { let c:number=0; this.each(()=>{ c++ }); return c; } /*** * * @param list */ public static of<K extends string|number,V>( list : MapType<K, V> ): ObjectStream<K,V> {return new ObjectStream<K, V>(list);} valueOfOptional(): Optional<MapType<K, V>> { return new Optional<MapType<K, V>>(this.list); } } /*** * */ export class ObjectStream<K extends string|number,V> extends AbstractObjectStream<K,V>{ constructor(value : MapType<K,V> ) {super(value);} }