export function getOrSet < T extends Record < keyof unknown , unknown > > ( record , key , defaultValue ) { if ( record [ key ] === undefined ) { record [ key ] = defaultValue instanceof Function ? defaultValue ( ) : defaultValue ; } return record [ key ] ; } export function fail ( message ? ) { throw new Error ( message || "Failed" ) ; } export function remove < T > ( array , t ) { const index = array . indexOf ( t ) ; if ( index > - 1 ) { array . splice ( index , 1 ) ; } } /** Returns 0 inclusive to n exclusive. */ export function zeroTo ( n ) { return [ ... Array ( n ) . keys ( ) ] ; } export function groupBy < T , Y = T > ( list , fn , valueFn ? ) { const result = new Map < string , Y [ ] > ( ) ; list . forEach ( ( o ) => { const group = fn ( o ) ; if ( ! result . has ( group ) ) { result . set ( group , [ ] ) ; } result . get ( group ) ! . push ( valueFn === undefined ? ( o as any as Y ) : valueFn ( o ) ) ; } ) ; return result ; } export function indexBy < T , Y = T > ( list , fn , valueFn ? ) { const result = new Map < string , Y > ( ) ; list . forEach ( ( o ) => { const group = fn ( o ) ; result . set ( group , valueFn === undefined ? ( o as any as Y ) : valueFn ( o ) ) ; } ) ; return result ; } export function partition < T > ( array , f ) { const trueElements = [ ] ; const falseElements = [ ] ; array . forEach ( ( el ) => { if ( f ( el ) ) { trueElements . push ( el ) ; } else { falseElements . push ( el ) ; } } ) ; return [ trueElements , falseElements ] ; } export function toArray < T > ( maybeArray ) { return Array . isArray ( maybeArray ) ? maybeArray : [ maybeArray ] ; } export type NullOrDefinedOr < T > = T | null | undefined ;