import { clamp } from './math' ; import type { Arrayable , Nullable } from './types' ; category export function toArray < T > ( array ? ) { array = array || [ ] ; if ( Array . isArray ( array ) ) return array ; return [ array ] ; } category export function flattenArrayable < T > ( array ? ) { return toArray ( array ) . flat ( 1 ) as Array < T > ; } category export function mergeArrayable < T > ( ... args ) { return args . flatMap ( i => toArray ( i ) ) ; } export type PartitionFilter < T > = ( i : T , idx : number , arr : readonly T [ ] ) => any ; category example export function partition < T > ( array , f1 ) ; export function partition < T > ( array , f1 , f2 ) ; export function partition < T > ( array , f1 , f2 , f3 ) ; export function partition < T > ( array , f1 , f2 , f3 , f4 ) ; export function partition < T > ( array , f1 , f2 , f3 , f4 , f5 ) ; export function partition < T > ( array , f1 , f2 , f3 , f4 , f5 , f6 ) ; export function partition < T > ( array , ... filters ) { const result = new Array ( filters . length + 1 ) . fill ( null ) . map ( ( ) => [ ] ) ; array . forEach ( ( e , idx , arr ) => { let i = 0 ; for ( const filter of filters ) { if ( filter ( e , idx , arr ) ) { result [ i ] . push ( e ) ; return ; } i += 1 ; } result [ i ] . push ( e ) ; } ) ; return result ; } category export function uniq < T > ( array ) { return Array . from ( new Set ( array ) ) ; } category export function last ( array ) ; export function last < T > ( array ) ; export function last < T > ( array ) { return at ( array , - 1 ) ; } category export function remove < T > ( array , value ) { if ( ! array ) return false ; const index = array . indexOf ( value ) ; if ( index >= 0 ) { array . splice ( index , 1 ) ; return true ; } return false ; } category export function at ( array , index ) ; export function at < T > ( array , index ) ; export function at < T > ( array , index ) { const len = array . length ; if ( ! len ) return undefined ; if ( index < 0 ) index += len ; return array [ index ] ; } category export function range ( stop ) ; export function range ( start , stop , step ? ) ; export function range ( ... args ) { let start , stop , step ; if ( args . length === 1 ) { start = 0 ; step = 1 ; ( [ stop ] = args ) ; } else { ( [ start , stop , step = 1 ] = args ) ; } const arr = [ ] ; let current = start ; while ( current < stop ) { arr . push ( current ) ; current += step || 1 ; } return arr ; } category param arr param from param to export function move < T > ( arr , from , to ) { arr . splice ( to , 0 , arr . splice ( from , 1 ) [ 0 ] ) ; return arr ; } category export function clampArrayRange ( n , arr ) { return clamp ( n , 0 , arr . length - 1 ) ; }