interface IArrayExtended < T > { removeLast ( ) : T ; empty ( ) : boolean ; contains ( e ) : boolean ; findBy ( e ) : T [ ] ; filterBy ( e ) : T [ ] ; sortBy ( e ) : T [ ] ; ifFound ( action ) : T [ ] ; ifEmpty ( action ) : T [ ] ; } export function extendArray < T > ( target = Array . prototype ) { const methods = [ 'removeLast' , 'empty' , 'contains' , 'findBy' , 'filterBy' , 'sortBy' , 'ifFound' , 'ifEmpty' ] ; for ( const m of methods ) Object . defineProperty ( target , m , { enumerable : false , writable : true } ) ; if ( ! target . removeLast ) { target . removeLast = function < T > ( ) : T { if ( this . length == 0 ) return null ; if ( this . length > 0 ) { const last = this . splice ( this . length - 1 , 1 ) ; return last [ 0 ] ; } } ; } if ( ! target . contains ) { target . contains = function < T > ( e ) : boolean { return this . indexOf ( e ) >= 0 ; } ; } if ( ! target . empty ) { target . empty = function < T > ( ) : boolean { return this . length == 0 ; } ; } if ( ! target . findBy ) { target . findBy = function < T > ( e ) : T [ ] { return this . filter ( ( item ) => { let include = true ; for ( const k in e ) { include = include && item [ k ] == e [ k ] ; } return include ; } ) ; } ; } if ( ! target . filterBy ) { target . filterBy = function < T > ( e ) : T [ ] { return this . findBy ( e ) ; } ; } if ( ! target . ifFound ) { target . ifFound = function < T > ( action ) : T [ ] { if ( this . length > 0 ) { action ( this [ 0 ] ) ; } return this ; } ; } if ( ! target . ifEmpty ) { target . ifEmpty = function < T > ( action ) : T [ ] { if ( this . length == 0 ) { action ( ) ; } return this ; } ; } if ( ! target . sortBy ) { target . sortBy = function < T > ( e ) : T [ ] { let key = '' ; let sorting = 1 ; for ( const ekey in e ) { key = ekey ; sorting = e [ ekey ] == 'asc' ? 1 : - 1 ; } return this . sort ( ( a1 , a2 ) => { if ( ! a1 ) return 1 ; if ( ! a1 [ key ] ) return 1 ; if ( ! a2 ) return - 1 ; if ( ! a2 [ key ] ) return 1 ; if ( isNumeric ( a1 [ key ] ) && isNumeric ( a2 [ key ] ) ) return ( a1 [ key ] - a2 [ key ] ) * sorting ; if ( isString ( a1 [ key ] ) && isString ( a2 [ key ] ) ) return a1 [ key ] . toLowerCase ( ) . localeCompare ( a2 [ key ] . toLowerCase ( ) ) * sorting ; } ) ; } ; } return target as any ; } function isNumeric ( n ) { return ! isNaN ( parseFloat ( n ) ) && isFinite ( n ) ; } function isString ( s ) { return typeof s === 'string' || s instanceof String ; } export { } ;