export interface SerializedSortedHash < TItem > { sequence : string [ ] ; hash : { [ key ] : TItem ; } ; } export class SortedHash < TItem > { private sequence : string [ ] ; private hash : { [ key ] : TItem ; } ; constructor ( defaultValue = { sequence : [ ] , hash : { } } ) { this . sequence = defaultValue . sequence ; this . hash = defaultValue . hash ; } add ( key , item ) { if ( this . hash [ key ] ) { throw new Error ( `Object with \`${ key }\` already exists.` ) ; } this . sequence . push ( key ) ; this . hash [ key ] = item ; } get ( key ) { return this . hash [ key ] ; } keys ( ) { return this . sequence ; } contains ( key ) { return key in this . hash ; } getList ( ) { return this . map ( item => item ) ; } map < TValue > ( callback ) { return this . sequence . map ( ( key , index ) => { return callback ( this . hash [ key ] , index ) ; } ) ; } forEach ( callback ) { return this . sequence . forEach ( ( key , index ) => { return callback ( this . hash [ key ] , index ) ; } ) ; } insertAtIndex ( key , item , index ) { this . sequence = [ ... this . sequence . slice ( 0 , index ) , key , ... this . sequence . slice ( index ) ] ; this . hash [ key ] = item ; } remove ( key ) { const index = this . sequence . indexOf ( key ) ; if ( index !== - 1 ) { this . sequence . splice ( index , 1 ) ; delete this . hash [ key ] ; } } serialize ( ) { return { sequence : [ ... this . sequence ] , hash : { ... this . hash } } ; } }