/**
 * An object which can produce an iterator over its values.
 */ export interface IIterable < T > { returns iter ( ) : IIterator < T > ; } /**
 * An object which traverses a collection of values.
 *
 * #### Notes
 * An `IIterator` is itself an `IIterable`. Most implementations of
 * `IIterator` should simply return `this` from the `iter()` method.
 */ export interface IIterator < T > extends IIterable < T > { returns clone ( ) : IIterator < T > ; returns next ( ) : T | undefined ; } /**
 * A type alias for an iterable or builtin array-like object.
 */ export type IterableOrArrayLike < T > = IIterable < T > | ArrayLike < T > ; param object returns export function iter < T > ( object ) { let it ; if ( typeof ( object as any ) . iter === 'function' ) { it = ( object as IIterable < T > ) . iter ( ) ; } else { it = new ArrayIterator < T > ( object as ArrayLike < T > ) ; } return it ; } param object returns export function iterKeys < T > ( object ) { return new KeyIterator ( object ) ; } param object returns export function iterValues < T > ( object ) { return new ValueIterator < T > ( object ) ; } param object returns export function iterItems < T > ( object ) { return new ItemIterator < T > ( object ) ; } param fn returns export function iterFn < T > ( fn ) { return new FnIterator < T > ( fn ) ; } param object param fn export function each < T > ( object , fn ) { let index = 0 ; let it = iter ( object ) ; let value ; while ( ( value = it . next ( ) ) !== undefined ) { if ( fn ( value , index ++ ) === false ) { return ; } } } param object param fn returns export function every < T > ( object , fn ) { let index = 0 ; let it = iter ( object ) ; let value ; while ( ( value = it . next ( ) ) !== undefined ) { if ( ! fn ( value , index ++ ) ) { return false ; } } return true ; } param object param fn returns export function some < T > ( object , fn ) { let index = 0 ; let it = iter ( object ) ; let value ; while ( ( value = it . next ( ) ) !== undefined ) { if ( fn ( value , index ++ ) ) { return true ; } } return false ; } param object returns export function toArray < T > ( object ) { let index = 0 ; let result = [ ] ; let it = iter ( object ) ; let value ; while ( ( value = it . next ( ) ) !== undefined ) { result [ index ++ ] = value ; } return result ; } param object returns export function toObject < T > ( object ) { let it = iter ( object ) ; let pair ; let result = { } ; while ( ( pair = it . next ( ) ) !== undefined ) { result [ pair [ 0 ] ] = pair [ 1 ] ; } return result ; } /**
 * An iterator for an array-like object.
 *
 * #### Notes
 * This iterator can be used for any builtin JS array-like object.
 */ export class ArrayIterator < T > implements IIterator < T > { param source constructor ( source ) { this . _source = source ; } returns iter ( ) { return this ; } returns clone ( ) { let result = new ArrayIterator < T > ( this . _source ) ; result . _index = this . _index ; return result ; } returns next ( ) { if ( this . _index >= this . _source . length ) { return undefined ; } return this . _source [ this . _index ++ ] ; } private _index = 0 ; private _source : ArrayLike < T > ; } /**
 * An iterator for the keys in an object.
 *
 * #### Notes
 * This iterator can be used for any JS object.
 */ export class KeyIterator implements IIterator < string > { param source param keys constructor ( source , keys = Object . keys ( source ) ) { this . _source = source ; this . _keys = keys ; } returns iter ( ) { return this ; } returns clone ( ) { let result = new KeyIterator ( this . _source , this . _keys ) ; result . _index = this . _index ; return result ; } returns next ( ) { if ( this . _index >= this . _keys . length ) { return undefined ; } let key = this . _keys [ this . _index ++ ] ; if ( key in this . _source ) { return key ; } return this . next ( ) ; } private _index = 0 ; private _keys : string [ ] ; private _source : { readonly [ key ] : any ; } ; } /**
 * An iterator for the values in an object.
 *
 * #### Notes
 * This iterator can be used for any JS object.
 */ export class ValueIterator < T > implements IIterator < T > { param source param keys constructor ( source , keys = Object . keys ( source ) ) { this . _source = source ; this . _keys = keys ; } returns iter ( ) { return this ; } returns clone ( ) { let result = new ValueIterator < T > ( this . _source , this . _keys ) ; result . _index = this . _index ; return result ; } returns next ( ) { if ( this . _index >= this . _keys . length ) { return undefined ; } let key = this . _keys [ this . _index ++ ] ; if ( key in this . _source ) { return this . _source [ key ] ; } return this . next ( ) ; } private _index = 0 ; private _keys : string [ ] ; private _source : { readonly [ key ] : T ; } ; } /**
 * An iterator for the items in an object.
 *
 * #### Notes
 * This iterator can be used for any JS object.
 */ export class ItemIterator < T > implements IIterator < [ string , T ] > { param source param keys constructor ( source , keys = Object . keys ( source ) ) { this . _source = source ; this . _keys = keys ; } returns iter ( ) { return this ; } returns clone ( ) { let result = new ItemIterator < T > ( this . _source , this . _keys ) ; result . _index = this . _index ; return result ; } returns next ( ) { if ( this . _index >= this . _keys . length ) { return undefined ; } let key = this . _keys [ this . _index ++ ] ; if ( key in this . _source ) { return [ key , this . _source [ key ] ] ; } return this . next ( ) ; } private _index = 0 ; private _keys : string [ ] ; private _source : { readonly [ key ] : T ; } ; } /**
 * An iterator for an iterator-like function.
 */ export class FnIterator < T > implements IIterator < T > { param fn constructor ( fn ) { this . _fn = fn ; } returns iter ( ) { return this ; } returns clone ( ) { throw new Error ( 'An `FnIterator` cannot be cloned.' ) ; } returns next ( ) { return this . _fn . call ( undefined ) ; } private _fn : ( ) => T | undefined ; }