fileoverview import _ from "lodash" ; import { Collection } from "./collection" ; export class SortedCollection < T > extends Collection < T > { private _sortedKeys : string [ ] = [ ] ; private _comparisonFunction ? : ( x : string , y : string ) => number = undefined ; param in_name param in_type constructor ( in_name ? , in_type ? ) { super ( in_name , in_type ) ; } param in_fn setComparisonFunction ( in_fn ? ) { console . assert ( _ . isFunction ( in_fn ) , "Must provide a function" ) ; this . _comparisonFunction = in_fn ; } param in_key param in_value returns add ( in_key , in_value ) { const toReturn = super . add ( in_key , in_value ) ; this . _sortedKeys . push ( in_key . toString ( ) ) ; this . _sortedKeys . sort ( this . _comparisonFunction ) ; return toReturn ; } param in_key returns remove ( in_key ) { const toReturn = super . remove ( in_key ) ; this . _sortedKeys = _ . without ( this . _sortedKeys , in_key ) ; return toReturn ; } returns clone ( ) { const newCol = new SortedCollection < T > ( this . _name , this . _type ) ; newCol . setComparisonFunction ( this . _comparisonFunction ) ; newCol . bulkAdd ( this . _items ) ; return newCol ; } param in_array param in_key returns private _binarySearchNearestIndex ( in_array , in_key ) { if ( this . _comparisonFunction === undefined ) { return _ . sortedIndex ( in_array , in_key ) ; } else { const middleIndex = Math . floor ( ( in_array . length - 1 ) / 2 ) ; if ( middleIndex < 0 ) { return 0 ; } if ( this . _comparisonFunction ( in_array [ middleIndex ] , in_key ) > 0 ) { if ( in_array . length === 1 ) { return 0 ; } return this . _binarySearchNearestIndex ( in_array . slice ( 0 , middleIndex ) , in_key ) ; } if ( this . _comparisonFunction ( in_array [ middleIndex ] , in_key ) < 0 ) { if ( in_array . length === 1 ) { return 1 ; } return ( middleIndex + 1 ) + this . _binarySearchNearestIndex ( in_array . slice ( middleIndex + 1 , in_array . length ) , in_key ) ; } return middleIndex ; } } param in_key returns getNearestNextItem ( in_key ) { const closestNextIndex = this . _binarySearchNearestIndex ( this . _sortedKeys , in_key . toString ( ) ) ; if ( closestNextIndex === this . getCount ( ) ) { return undefined ; } else { return this . item ( this . _sortedKeys [ closestNextIndex ] ) ; } } param in_key returns getNearestPreviousItem ( in_key ) { const closestPreviousIndex = this . _binarySearchNearestIndex ( this . _sortedKeys , in_key . toString ( ) ) ; if ( closestPreviousIndex === 0 ) { return undefined ; } else { return this . item ( this . _sortedKeys [ closestPreviousIndex - 1 ] ) ; } } }