import { PropGetter , Strategy } from './common-interfaces' ; export enum SortDirection { DESC = 'DESC' , ASC = 'ASC' } example export class Sorting < T > { private propGetter : PropGetter < T > ; private strategy : Strategy = new SortDescStrategy < T > ( ) ; /** Set index property of T which uses for sorting. */ setIndexPropGetter ( propGetter ) { this . propGetter = propGetter ; return this ; } setDirection ( direction ) { switch ( direction ) { case SortDirection . ASC : this . strategy = new SortAscStrategy < T > ( ) ; break ; case SortDirection . DESC : this . strategy = new SortDescStrategy < T > ( ) ; break ; } return this ; } sort ( items ) { this . strategy . execute ( items , this . propGetter ) ; } } const sortFn = ( direction ) => ( a , b ) : number => { if ( a < b ) { return - 1 * direction ; } else if ( a > b ) { return 1 * direction ; } return 0 ; } ; function getIndexProps < T > ( a , b , propGetter ) { let aProp ; let bProp ; try { aProp = propGetter ( a ) ; bProp = propGetter ( b ) ; } catch ( error ) { console . error ( 'Error during getting props.' , error ) ; } return [ aProp , bProp ] ; } export class SortDescStrategy < T > extends Strategy { execute ( items , propGetter ) { items . sort ( ( a , b ) : number => { const [ aProp , bProp ] = getIndexProps ( a , b , propGetter ) ; return sortFn ( - 1 ) ( aProp , bProp ) ; } ) ; } } export class SortAscStrategy < T > extends Strategy { execute ( items , propGetter ) { items . sort ( ( a , b ) : number => { const [ aProp , bProp ] = getIndexProps ( a , b , propGetter ) ; return sortFn ( 1 ) ( aProp , bProp ) ; } ) ; } }