import { isNumberArray , nonNullish } from '@lib/functions' ; import { asc , desc , max , min , mult , sum } from '@lib/math' ; import { SizedTuple } from '@lib/model' ; import { addAllToSet } from '@lib/set' ; import { pairsWith } from '.' ; import { cutSubSegment } from './cut-subsegment.function' ; import { findEndOfPair } from './find-end-of-pair.function' ; import { matrixFlipFlop } from './flip-flop.generator' ; import { flipMatrix } from './flip-matrix.function' ; import { mean } from './mean.function' ; import { median } from './median.function' ; import { partition } from './partition.function' ; import { peek } from './peek.function' ; import { rotateMatrix } from './rotate-matrix.function' ; import { slideWindow } from './slide-window.function' ; declare global { interface Array < T > { first ( ) : T ; last ( ) : T ; findEndOfPair ( pairs , from ) : number | undefined ; cutSubSegment ( pairs , from ) : T [ ] | undefined ; removeItem ( item ) : boolean ; flipMatrix ( axis ) : T [ ] ; rotateMatrix ( direction ) : T [ ] ; flipFlop ( ) : Generator < T [ ] > ; contains ( item ) : boolean ; intoSet ( set ? ) : Set < T > ; has ( item ) : boolean ; tap ( callbackFn ) : T [ ] ; toInt ( options ? ) : number [ ] ; intoIter ( ) : IterableIterator < T > ; repeat ( until ? ) : IterableIterator < T > ; sum ( ) : number ; product ( ) : number ; min ( ) : T ; max ( ) : T ; asc ( ) : T [ ] ; desc ( ) : T [ ] ; clone ( ) : T [ ] ; count ( predicate ) : number ; /**
         * Returns the last element
         */ peek ( ) : T ; /**
         * Return the middle element
         */ median ( ) : number ; /**
         * Return the average value of the array
         */ mean ( ) : number ; mapFilter < V > ( mapFn ) : V [ ] ; partition ( partitioner ) : [ T [ ] , T [ ] ] ; slideWindow < N extends number > ( windowSize ? ) : SizedTuple < T , N > [ ] ; bubbleFindPair ( comparator ) : [ T , T ] ; unique ( comparator ? ) : T [ ] ; pairsWith < N = T > ( other ? , onlyUnique ? ) : [ T , N ] [ ] ; } } Array . prototype . intoIter = function * < T > ( ) : IterableIterator < T > { for ( const element of this ) { yield element ; } } ; Array . prototype . repeat = function * < T > ( until ) : IterableIterator < T > { for ( let i = 0 ; ; i ++ ) { for ( const element of this ) { yield element ; if ( until ?. ( element , i ) ) { return ; } } } } ; Array . prototype . pairsWith = function < T , N = T > ( other ? , onlyUnique = false ) : [ T , N ] [ ] { return pairsWith ( this , other , onlyUnique ) ; } ; Array . prototype . first = function < T > ( ) : T { return this [ 0 ] ; } ; Array . prototype . last = function < T > ( ) : T { return this [ this . length - 1 ] ; } ; Array . prototype . unique = function < T > ( comparator ? ) : T [ ] { const result = [ ] ; for ( const item of this ) { if ( ! result . some ( ( r ) => ( comparator ? comparator ( r , item ) : r === item ) ) ) { result . push ( item ) ; } } return result ; } ; Array . prototype . mapFilter = function < T , V > ( mapFn ) : V [ ] { const result = [ ] ; for ( const item of this ) { const value = mapFn ( item ) ; if ( nonNullish ( value ) ) { result . push ( value ) ; } } return result ; } ; Array . prototype . tap = function < T > ( callbackFn ) : T [ ] { for ( const item of this ) { callbackFn ( item ) ; } return this ; } ; Array . prototype . mean = function ( ) : number { if ( ! isNumberArray ( this ) ) { throw new Error ( 'Mean can only be calculated for number[]' ) ; } return mean ( this ) ; } ; Array . prototype . median = function ( ) : number { if ( ! isNumberArray ( this ) ) { throw new Error ( 'Median can only be calculated for number[]' ) ; } return median ( this ) ; } ; Array . prototype . peek = function < T > ( ) : T { return peek ( this ) ; } ; Array . prototype . count = function < T > ( predicate ) : number { let count = 0 ; for ( const element of this ) { if ( predicate ( element ) ) { count ++ ; } } return count ; } ; Array . prototype . slideWindow = function < T , N extends number > ( windowSize = 2 as N ) : SizedTuple < T , N > [ ] { return slideWindow ( this , windowSize ) ; } ; Array . prototype . partition = function < T > ( partitioner ) : [ T [ ] , T [ ] ] { return partition ( this , partitioner ) ; } ; Array . prototype . bubbleFindPair = function < T > ( comparator ) : [ T | undefined , T | undefined ] { for ( let i = 0 ; i < this . length - 1 ; i ++ ) { const ei = this [ i ] ; for ( let j = i + 1 ; j < this . length ; j ++ ) { const ej = this [ j ] ; if ( comparator ( ei , ej ) ) { return [ ei , ej ] ; } } } return [ undefined , undefined ] ; } ; Array . prototype . has = function < T > ( item ) : boolean { return this . find ( ( i ) => i === item ) !== undefined ; } ; Array . prototype . toInt = function ( options ? ) : number [ ] { let result = this . map ( ( i ) => parseInt ( i , options ?. radix ?? 10 ) ) ; if ( options ?. safe ) { result = result . filter ( ( i ) => ! isNaN ( i ) ) ; } return result ; } ; Array . prototype . clone = function < T > ( ) : T [ ] { return Array . from ( this ) ; } ; Array . prototype . desc = function < T > ( ) : T [ ] { return this . sort ( desc ) ; } ; Array . prototype . asc = function < T > ( ) : T [ ] { return this . sort ( asc ) ; } ; Array . prototype . min = function < T > ( ) : T { return this . length ? this . reduce ( min , Infinity ) : undefined ; } ; Array . prototype . max = function < T > ( ) : T { return this . length ? this . reduce ( max , - Infinity ) : undefined ; } ; Array . prototype . sum = function ( ) : number { return this . reduce ( sum , 0 ) ; } ; Array . prototype . product = function ( ) : number { return this . reduce ( mult , 1 ) ; } ; Array . prototype . intoSet = function < T > ( set ? ) : Set < T > { return addAllToSet ( this , set ) ; } ; Array . prototype . contains = function < T > ( item ) : boolean { return this . find ( ( i ) => i === item ) !== undefined ; } ; Array . prototype . flipFlop = function * < T > ( ) : Generator < T [ ] [ ] > { yield * matrixFlipFlop ( this ) ; } ; Array . prototype . flipMatrix = function < T > ( axis = 'x' ) : T [ ] [ ] { return flipMatrix ( this , axis ) ; } ; Array . prototype . rotateMatrix = function < T > ( direction = 'r' ) : T [ ] [ ] { return rotateMatrix ( this , direction ) ; } ; Array . prototype . findEndOfPair = function < T > ( pairs , from = 0 ) : number | undefined { return findEndOfPair ( this , pairs , from ) ; } ; Array . prototype . cutSubSegment = function < T > ( pairs , from = 0 ) : T [ ] | undefined { return cutSubSegment ( this , pairs , from ) ; } ; Array . prototype . removeItem = function < T > ( item ) : boolean { const index = this . findIndex ( ( e ) => e === item ) ; if ( index >= 0 ) { this . splice ( index , 1 ) ; } return index >= 0 ; } ;