swiss-ak v2.13.2
swiss-ak (Swiss Army Knife)
A collection of useful little things that I like to reuse across projects
times
A collection of Tools for calculating simple times.
Each unit (e.g. second) has: a type (second), a constant (SECOND) and a function for getting multiples (seconds(x: second) => ms)
| unit | type | constant | function | 
|---|---|---|---|
| millisecond | ms | MILLISECOND | milliseconds(x: ms) => ms | 
| second | second | SECOND | seconds(x: second) => ms | 
| minute | minute | MINUTE | minutes(x: minute) => ms | 
| hour | hour | HOUR | hours(x: hour) => ms | 
| day | day | DAY | days(x: day) => ms | 
| week | week | WEEK | weeks(x: week) => ms | 
| month | month | MONTH | months(x: month) => ms | 
| year | year | YEAR | years(x: year) => ms | 
| decade | decade | DECADE | decades(x: decade) => ms | 
| century | century | CENTURY | centuries(x: century) => ms | 
| millennium | millennium | MILLENNIUM | millenniums(x: millennium) => ms | 
waiters
Async functions that return promises at or after a given time.
'Accurate/pinged' waiters ping at intermediary points to resolve at a more accurate time.
| Name | Description | Example | 
|---|---|---|
| wait | Standard wait promise (using setTimeout) | minutes(2)= in 2 minutes | 
| waitFor | Accurate (pinged) wait the given ms | minutes(2)= in 2 minutes | 
| waitUntil | Accurate (pinged) wait until given time | Date.now() + minutes(2)= in 2 minutes | 
| waitEvery | Accurate (pinged) wait for next 'every X' event | hours(1)= next full hour (e.g. 17:00, 22:00) | 
| interval | Accurate (pinged) interval for every 'every X' event | hours(1)= every hour, on the hour | 
wait
wait(time: ms): Promise<unknown>
waiters.wait(time: ms): Promise<unknown>Standard wait promise (using setTimeout)
import { wait } from 'swiss-ak';
console.log(new Date().toTimeString()); // 12:30:10
await wait(minutes(2));
console.log(new Date().toTimeString()); // 12:32:10| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | time | Yes | ms | 
| Return Type | 
|---|
| Promise<unknown> | 
waitUntil
waitUntil(time: ms): Promise<null>
waiters.waitUntil(time: ms): Promise<null>Accurate (pinged) wait until given time
import { waitUntil } from 'swiss-ak';
console.log(new Date().toTimeString()); // 12:30:10
await waitUntil(Date.now() + minutes(10));
console.log(new Date().toTimeString()); // 12:40:10| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | time | Yes | ms | 
| Return Type | 
|---|
| Promise<null> | 
waitFor
waitFor(time: ms): Promise<null>
waiters.waitFor(time: ms): Promise<null>Accurate (pinged) wait the given ms
import { waitFor } from 'swiss-ak';
console.log(new Date().toTimeString()); // 12:30:10
await waitFor(minutes(5));
console.log(new Date().toTimeString()); // 12:35:10| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | time | Yes | ms | 
| Return Type | 
|---|
| Promise<null> | 
waitEvery
waitEvery(timing: ms, offset: ms): Promise<null>
waiters.waitEvery(timing: ms, offset: ms): Promise<null>Accurate (pinged) wait for next 'every X' event
import { waitEvery } from 'swiss-ak';
console.log(new Date().toTimeString()); // 12:30:10
await waitEvery(hours(2));
console.log(new Date().toTimeString()); // 14:00:00| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | timing | Yes | ms | 
| 1 | offset | No | ms | 
| Return Type | 
|---|
| Promise<null> | 
stopInterval
stopInterval(intID: number): void
waiters.stopInterval(intID: number): voidimport { interval, stopInterval } from 'swiss-ak';
console.log(new Date().toTimeString()); // 12:30:10
interval((intID, count) => {
  console.log(new Date().toTimeString()); // 13:00:00, 14:00:00, 15:00:00
  if (count === 3) {
    stopInterval(intID);
  }
}, hours(1));| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | intID | Yes | number | 
| Return Type | 
|---|
| void | 
interval
interval(action: (intID?: number, count?: number) => any, timing: ms): number
waiters.interval(action: (intID?: number, count?: number) => any, timing: ms): numberAccurate (pinged) interval for every 'every X' event
import { interval, stopInterval } from 'swiss-ak';
console.log(new Date().toTimeString()); // 12:30:10
interval((intID, count) => {
  console.log(new Date().toTimeString()); // 13:00:00, 14:00:00, 15:00:00
  if (count === 3) {
    stopInterval(intID);
  }
}, hours(1));| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | action | Yes | (intID?: number, count?: number) => any | 
| 1 | timing | Yes | ms | 
| Return Type | 
|---|
| number | 
fn
A collection of useful higher-order functions.
noop
fn.noop(): voidNo operation. Do nothing, return nothing.
const run = condition ? doSomething : fn.noop;
run();| Return Type | 
|---|
| void | 
noact
fn.noact(item: T): TNo action. Returns the first argument it receives.
const items = stuff
  .map(condition ? mapSomething : fn.noact)| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | No | T | 
| Return Type | 
|---|
| T | 
result
fn.result(item: T): () => TReturns a function that returns the first argument.
const items = stuff
  .filter(condition ? mapSomething : fn.result(true))| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | No | T | 
| Return Type | 
|---|
| () => T | 
resolve
fn.resolve(item: T): () => Promise<T>Returns an async function that resolves to the first argument
Like fn.result, but wrapped in a Promise
| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | No | T | 
| Return Type | 
|---|
| () => Promise<T> | 
reject
fn.reject(item: T): () => Promise<T>Returns an async function that rejects with the first argument
| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | No | T | 
| Return Type | 
|---|
| () => Promise<T> | 
filters
fn.filters;Collection of functions that can be used with Array.filter
exists
fn.exists(item: T): boolean
fn.filters.exists(item: T): boolean
filters.exists(item: T): booleanReturns true if item isn't null or undefined.
[null, 1, undefined, 2].filter(fn.exists); // [1, 2]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| boolean | 
isTruthy
fn.isTruthy(item: T): boolean
fn.filters.isTruthy(item: T): boolean
filters.isTruthy(item: T): booleanReturns true if item is truthy.
[0, 1, 2].filter(fn.isTruthy); // [1, 2]
['', 'a', 'b'].filter(fn.isTruthy); // ['a', 'b']| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| boolean | 
isFalsy
fn.isFalsy(item: T): boolean
fn.filters.isFalsy(item: T): boolean
filters.isFalsy(item: T): booleanReturns true if item is falsy.
[0, 1, 2].filter(fn.isFalsy); // [0]
['', 'a', 'b'].filter(fn.isFalsy); // ['']| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| boolean | 
isEmpty
fn.isEmpty(item: T[] | string): boolean
fn.filters.isEmpty(item: T[] | string): boolean
filters.isEmpty(item: T[] | string): booleanReturns true if item's length is 0
['', 'a', 'b'].filter(fn.isEmpty); // ['']
[[], [1], [2]].filter(fn.isEmpty); // [[]]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T[] \| string | 
| Return Type | 
|---|
| boolean | 
isNotEmpty
fn.isNotEmpty(item: T[] | string): boolean
fn.filters.isNotEmpty(item: T[] | string): boolean
filters.isNotEmpty(item: T[] | string): booleanReturns true if item's length is 1 or more
['', 'a', 'b'].filter(fn.isNotEmpty); // ['a', 'b']
[[], [1], [2]].filter(fn.isNotEmpty); // [[1], [2]]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T[] \| string | 
| Return Type | 
|---|
| boolean | 
isEqual
fn.isEqual(item: T): (other: T) => boolean
fn.filters.isEqual(item: T): (other: T) => boolean
filters.isEqual(item: T): (other: T) => booleanReturns a function that returns true if the item is equal to provided value.
[0, 1, 2].filter(fn.isEqual(1)); // [1]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| (other: T) => boolean | 
isNotEqual
fn.isNotEqual(item: T): (other: T) => boolean
fn.filters.isNotEqual(item: T): (other: T) => boolean
filters.isNotEqual(item: T): (other: T) => booleanReturns a function that returns true if the item is not equal to provided value.
[0, 1, 2].filter(fn.isNotEqual(1)); // [0, 2]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| (other: T) => boolean | 
dedupe
fn.dedupe(item: T, index: number, array: T[]): boolean
fn.filters.dedupe(item: T, index: number, array: T[]): boolean
filters.dedupe(item: T, index: number, array: T[]): booleanRemoves duplicate items from an array.
[0, 1, 2, 1, 0].filter(fn.dedupe); // [0, 1, 2]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| 1 | index | Yes | number | 
| 2 | array | Yes | T[] | 
| Return Type | 
|---|
| boolean | 
dedupeMapped
fn.dedupeMapped(mapFn: (value?: T, index?: number, array?: T[]) => U): (item: T, index: number, array: T[]) => boolean
fn.filters.dedupeMapped(mapFn: (value?: T, index?: number, array?: T[]) => U): (item: T, index: number, array: T[]) => boolean
filters.dedupeMapped(mapFn: (value?: T, index?: number, array?: T[]) => U): (item: T, index: number, array: T[]) => booleanRemoves duplicate items from an array based on a mapped value.
[2, 4, 6, 8, 10, 12].filter(fn.dedupeMapped((v) => v % 3)); // [ 2, 4, 6 ] (maps to [ 2, 1, 0, 2, 1, 0 ])| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | mapFn | Yes | (value?: T, index?: number, array?: T[]) => U | 
| Return Type | 
|---|
| (item: T, index: number, array: T[]) => boolean | 
maps
fn.maps;Collection of functions that can be used with Array.map
toString
fn.toString(item: T): string
fn.maps.toString(item: T): string
maps.toString(item: T): stringMaps the item to a string.
[0, 1, 2].map(fn.toString); // ['0', '1', '2']| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| string | 
toNumber
fn.toNumber(item: T): number
fn.maps.toNumber(item: T): number
maps.toNumber(item: T): numberMaps the item to a number.
['0', '1', '2'].map(fn.toNumber); // [0, 1, 2]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| number | 
toBool
fn.toBool(item: T): boolean
fn.maps.toBool(item: T): boolean
maps.toBool(item: T): booleanMaps the item to a boolean.
[0, 1, 2].map(fn.toBool); // [false, true, true]
['true', 'false', '', 'text'].map(fn.toBool); // [true, false, false, true]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | item | Yes | T | 
| Return Type | 
|---|
| boolean | 
toProp
fn.toProp(prop: string | number): (item: O) => P
fn.maps.toProp(prop: string | number): (item: O) => P
maps.toProp(prop: string | number): (item: O) => PMaps the item to a given property of the item
[{name: 'Jack'}, {name: 'Jill'}].map(fn.toProp('name')); // ['Jack', 'Jill']| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | prop | Yes | string \| number | 
| Return Type | 
|---|
| (item: O) => P | 
toFixed
fn.toFixed(precision: number): (num: number) => number
fn.maps.toFixed(precision: number): (num: number) => number
maps.toFixed(precision: number): (num: number) => numberMap the items (numbers) of an array to a fixed precision.
[1.234, 5.678, 9.012].map(fn.toFixed(2)); // [1.23, 5.68, 9.01]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | precision | Yes | number | 
| Return Type | 
|---|
| (num: number) => number | 
sorts
fn.sorts;Collection of functions that can be used with Array.sort
asc
fn.asc(a: any, b: any): number
fn.sorts.asc(a: any, b: any): number
sorts.asc(a: any, b: any): numberSort ascending.
[2, 4, 3, 1].sort(fn.asc); // [1, 2, 3, 4]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | a | Yes | any | 
| 1 | b | Yes | any | 
| Return Type | 
|---|
| number | 
desc
fn.desc(a: any, b: any): number
fn.sorts.desc(a: any, b: any): number
sorts.desc(a: any, b: any): numberSort descending.
[2, 4, 3, 1].sort(fn.asc); // [4, 3, 2, 1]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | a | Yes | any | 
| 1 | b | Yes | any | 
| Return Type | 
|---|
| number | 
byProp
fn.byProp(propName: string | number, sortFn: SortFn<T>): SortFn<O>
fn.sorts.byProp(propName: string | number, sortFn: SortFn<T>): SortFn<O>
sorts.byProp(propName: string | number, sortFn: SortFn<T>): SortFn<O>Sort by a given property.
const people = [{age: 2}, {age: 4}, {age: 3}, {age: 1}];
people.sort(fn.byProp('age', fn.asc)); // [{age: 1}, {age: 2}, {age: 3}, {age: 4}]| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | propName | Yes | string \| number | |
| 1 | sortFn | No | SortFn<T> | asc | 
| Return Type | 
|---|
| SortFn<O> | 
nearestTo
fn.nearestTo(target: T): (a: any, b: any) => number
fn.sorts.nearestTo(target: T): (a: any, b: any) => number
sorts.nearestTo(target: T): (a: any, b: any) => numberSort by the nearest value to the given value.
Values get converted to numbers before comparison.
const people = [2, 4, 3, 1];
people.sort(fn.nearestTo(3)); // [3, 2, 4, 1]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | target | Yes | T | 
| Return Type | 
|---|
| (a: any, b: any) => number | 
furthestFrom
fn.furthestFrom(target: T): (a: any, b: any) => number
fn.sorts.furthestFrom(target: T): (a: any, b: any) => number
sorts.furthestFrom(target: T): (a: any, b: any) => numberSort by the furthest value to the given value.
const people = [2, 4, 3, 1];
people.sort(fn.furthestFrom(3)); // [1, 2, 4, 3]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | target | Yes | T | 
| Return Type | 
|---|
| (a: any, b: any) => number | 
array
fn.array(sortFn: SortFn<T>): (a: T[], b: T[]) => number
fn.sorts.array(sortFn: SortFn<T>): (a: T[], b: T[]) => number
sorts.array(sortFn: SortFn<T>): (a: T[], b: T[]) => numberSort an array of arrays by the given sort function.
Sorts by the first item in the array, then the second, etc. until a non-zero result is found.
| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | sortFn | No | SortFn<T> | asc | 
| Return Type | 
|---|
| (a: T[], b: T[]) => number | 
arrayAsc
fn.arrayAsc;
fn.sorts.arrayAsc;
sorts.arrayAsc;Sort an array of arrays in ascending order
Sorts by the first item in the array, then the second, etc. until a non-zero result is found.
arrayDesc
fn.arrayDesc;
fn.sorts.arrayDesc;
sorts.arrayDesc;Sort an array of arrays in descending order
Sorts by the first item in the array, then the second, etc. until a non-zero result is found.
reduces
fn.reduces;Collection of functions that can be used with Array.reduce
combine
fn.combine(a: T, b: T): T
fn.reduces.combine(a: T, b: T): T
reduces.combine(a: T, b: T): TAdds or concats the items
[1, 2, 3].reduce(fn.combine); // 6
['a', 'b', 'c'].reduce(fn.combine); // 'abc'| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | a | Yes | T | 
| 1 | b | Yes | T | 
| Return Type | 
|---|
| T | 
combineProp
fn.combineProp(propName: string | number): (a: O | T, b: O) => T
fn.reduces.combineProp(propName: string | number): (a: O | T, b: O) => T
reduces.combineProp(propName: string | number): (a: O | T, b: O) => TAdds or concats the given property of the items
const people = [{name: 'a', age: 1}, {name: 'b', age: 2}, {name: 'c', age: 3}];
people.reduce(fn.combineProp('age')); // 6
people.reduce(fn.combineProp('name')); // 'abc'| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | propName | Yes | string \| number | 
| Return Type | 
|---|
| (a: O \| T, b: O) => T | 
mode
fn.mode(prev: T, curr: T, index: number, arr: T[]): T
fn.reduces.mode(prev: T, curr: T, index: number, arr: T[]): T
reduces.mode(prev: T, curr: T, index: number, arr: T[]): TReturns the most common value in an array.
[1, 2, 3, 2, 1, 1].reduce(fn.mode); // 1| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | prev | Yes | T | 
| 1 | curr | Yes | T | 
| 2 | index | Yes | number | 
| 3 | arr | Yes | T[] | 
| Return Type | 
|---|
| T | 
modeMapped
fn.modeMapped(mapFn: (value: T, index: number, array: T[]) => U): (prev: T, curr: T, index: number, arr: T[]) => T
fn.reduces.modeMapped(mapFn: (value: T, index: number, array: T[]) => U): (prev: T, curr: T, index: number, arr: T[]) => T
reduces.modeMapped(mapFn: (value: T, index: number, array: T[]) => U): (prev: T, curr: T, index: number, arr: T[]) => TReturns the most common value in an array, based on a given map function.
[2, 4, 6, 8, 9, 12].reduce(fn.modeMapped((v) => v % 3)); // 6 (maps to [ 2, 1, 0, 2, 0, 0 ])| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | mapFn | Yes | (value: T, index: number, array: T[]) => U | 
| Return Type | 
|---|
| (prev: T, curr: T, index: number, arr: T[]) => T | 
everys
fn.everys;Collection of functions that can be used with Array.every
isAllEqual
fn.isAllEqual(val: T, i: number, arr: T[]): boolean
fn.everys.isAllEqual(val: T, i: number, arr: T[]): boolean
everys.isAllEqual(val: T, i: number, arr: T[]): booleanReturns if all the items are equal to one another.
[1, 1, 1].every(fn.isAllEqual); // true
[1, 2, 1].every(fn.isAllEqual); // false| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | val | Yes | T | 
| 1 | i | Yes | number | 
| 2 | arr | Yes | T[] | 
| Return Type | 
|---|
| boolean | 
isUnique
fn.isUnique(val: T, i: number, arr: T[]): boolean
fn.everys.isUnique(val: T, i: number, arr: T[]): boolean
everys.isUnique(val: T, i: number, arr: T[]): booleanReturns true if the item is unique in the array.
[1, 1, 1].every(fn.isUnique); // false
[1, 2, 1].every(fn.isUnique); // false
[1, 2, 3].every(fn.isUnique); // true| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | val | Yes | T | 
| 1 | i | Yes | number | 
| 2 | arr | Yes | T[] | 
| Return Type | 
|---|
| boolean | 
groups
fn.groups;Collection of functions that can be used with ArrayTools.group
bySize
fn.bySize(size: number): (value: T, index: number, array: T[]) => number
fn.groups.bySize(size: number): (value: T, index: number, array: T[]) => number
groups.bySize(size: number): (value: T, index: number, array: T[]) => numberGroup an array into groups of a given size.
Note: The last group may be smaller than the given size.
Note: The groups a distributed in order, so the first group will be filled up first, then the next, etc.
const nums = [1, 2, 3, 4, 5, 6, 7, 8];
ArrayTools.group(nums, fn.bySize(3)); // [[1, 2, 3], [4, 5, 6], [7, 8]]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | size | Yes | number | 
| Return Type | 
|---|
| (value: T, index: number, array: T[]) => number | 
byNumGroups
fn.byNumGroups(numGroups: number): (value: T, index: number, array: T[]) => any
fn.groups.byNumGroups(numGroups: number): (value: T, index: number, array: T[]) => any
groups.byNumGroups(numGroups: number): (value: T, index: number, array: T[]) => anyGroup an array into a certain number of groups as evenly as possible.
Note: The groups a distributed in order, so the first group will be filled up first, then the next, etc.
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ArrayTools.group(nums, byNumGroups(3)); // [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | numGroups | Yes | number | 
| Return Type | 
|---|
| (value: T, index: number, array: T[]) => any | 
ArrayTools
A collection of useful array functions.
create
create(length: number, value: T): T[]
ArrayTools.create(length: number, value: T): T[]Create an array of the given length, where each value is the given value
| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | length | No | number | 1 | 
| 1 | value | No | T | 1 as T | 
| Return Type | 
|---|
| T[] | 
filled
filled(length: number, value: T): T[]
ArrayTools.filled(length: number, value: T): T[]Create an array of the given length, where each value is the given value
| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | length | No | number | 1 | 
| 1 | value | Yes | T | 
| Return Type | 
|---|
| T[] | 
range
range(length: number, multiplier: number, offset: number): number[]
ArrayTools.range(length: number, multiplier: number, offset: number): number[]Returns an array of the given length, where each value is equal to it's index e.g. 0, 1, 2, ..., length
ArrayTools.range(3);  // [0, 1, 2]
ArrayTools.range(5);  // [0, 1, 2, 3, 4]
ArrayTools.range(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ArrayTools.range(3, 2);  // [0, 2, 4]
ArrayTools.range(5, 2);  // [0, 2, 4, 6, 8]
ArrayTools.range(10, 10); // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | length | No | number | 1 | 
| 1 | multiplier | No | number | 1 | 
| 2 | offset | No | number | 0 | 
| Return Type | 
|---|
| number[] | 
zip
zip(...arrs: T[]): ZippedArrays<T>[]
ArrayTools.zip(...arrs: T[]): ZippedArrays<T>[]Converts multiple arrays into an array of 'tuples' for each value at the corresponding indexes.
Limited to the length of the shortest provided array
Inspired by python's 'zip'
ArrayTools.zip([1, 2, 3, 4], ['a', 'b', 'c']); // [ [1, 'a'], [2, 'b'], [3, 'c'] ]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0… | arrs | No | T[] | 
| Return Type | 
|---|
| ZippedArrays<T>[] | 
zipMax
zipMax(...arrs: T[]): ZippedArrays<T>[]
ArrayTools.zipMax(...arrs: T[]): ZippedArrays<T>[]Converts multiple arrays into an array of 'tuples' for each value at the corresponding indexes.
Unlike zip, it will match the length of the longest provided array, filling in any missing values with undefined
Inspired by python's 'zip'
ArrayTools.zipMax([1, 2, 3, 4], ['a', 'b', 'c']); //[ [ 1, 'a' ], [ 2, 'b' ], [ 3, 'c' ], [ 4, undefined ] ]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0… | arrs | No | T[] | 
| Return Type | 
|---|
| ZippedArrays<T>[] | 
sortByMapped
sortByMapped(arr: T[], mapFn: (value: T, index: number, array: T[]) => M, sortFn: (a: M, b: M) => number): T[]
ArrayTools.sortByMapped(arr: T[], mapFn: (value: T, index: number, array: T[]) => M, sortFn: (a: M, b: M) => number): T[]Sort an array by a mapped form of the values, but returning the initial values
ArrayTools.sortByMapped(['2p', '3p', '1p'], (v) => Number(v.replace('p', ''))); // ['1p', '2p', '3p']
ArrayTools.sortByMapped(
  ['2p', '3p', '1p'],
  (v) => Number(v.replace('p', '')),
  (a, b) => b - a
); // ['3p', '2p', '1p']| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | arr | Yes | T[] | |
| 1 | mapFn | Yes | (value: T, index: number, array: T[]) => M | |
| 2 | sortFn | No | (a: M, b: M) => number | fn.asc | 
| Return Type | 
|---|
| T[] | 
randomise
randomise(arr: T[]): T[]
ArrayTools.randomise(arr: T[]): T[]Returns a clone of the provided array with it's items in a random order
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 5, 3, 4, 1, 2, 6 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 5, 1, 3, 2, 4, 6 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 6, 1, 4, 5, 2, 3 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 1, 4, 5, 2, 3, 6 ]
ArrayTools.randomise([1, 2, 3, 4, 5, 6]); // [ 2, 6, 1, 3, 4, 5 ]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | arr | Yes | T[] | 
| Return Type | 
|---|
| T[] | 
reverse
reverse(arr: T[]): T[]
ArrayTools.reverse(arr: T[]): T[]Returns a new array with the order reversed without affecting original array
const arr1 = [1, 2, 3];
arr1            // [1, 2, 3]
arr1.reverse(); // [3, 2, 1]
arr1            // [3, 2, 1]
const arr2 = [1, 2, 3];
arr2            // [1, 2, 3]
ArrayTools.reverse(arr2);  // [3, 2, 1]
arr2            // [1, 2, 3]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | arr | Yes | T[] | 
| Return Type | 
|---|
| T[] | 
entries
entries(arr: T[]): [number, T][]
ArrayTools.entries(arr: T[]): [number, T][]Returns array of 'tuples' of index/value pairs
const arr = ['a', 'b', 'c'];
ArrayTools.entries(arr); // [ [0, 'a'], [1, 'b'], [2, 'c'] ]
for (let [index, value] of entries(arr)) {
 console.log(index); // 0, 1, 2
 console.log(value); // 'a', 'b', 'c'
}| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | arr | Yes | T[] | 
| Return Type | 
|---|
| [number, T][] | 
repeat
repeat(maxLength: number, ...items: T[]): T[]
ArrayTools.repeat(maxLength: number, ...items: T[]): T[]Returns an array with the given items repeated
ArrayTools.repeat(5, 'a'); // [ 'a', 'a', 'a', 'a', 'a' ]
ArrayTools.repeat(5, 'a', 'b'); // [ 'a', 'b', 'a', 'b', 'a' ]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | maxLength | Yes | number | 
| 1… | items | No | T[] | 
| Return Type | 
|---|
| T[] | 
roll
roll(distance: number, arr: T[]): T[]
ArrayTools.roll(distance: number, arr: T[]): T[]'Roll' the array by a given amount so that is has a new first item. Length and contents remain the same, but the order is changed
ArrayTools.roll(1, [0, 1, 2, 3, 4, 5, 6, 7]); // [ 1, 2, 3, 4, 5, 6, 7, 0 ]
ArrayTools.roll(4, [0, 1, 2, 3, 4, 5, 6, 7]); // [ 4, 5, 6, 7, 0, 1, 2, 3 ]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | distance | Yes | number | 
| 1 | arr | Yes | T[] | 
| Return Type | 
|---|
| T[] | 
sortNumberedText
sortNumberedText(texts: string[], ignoreCase: boolean): string[]
ArrayTools.sortNumberedText(texts: string[], ignoreCase: boolean): string[]Alphabetically sorts a list of strings, but keeps multi-digit numbers in numerical order (rather than alphabetical)
const names = ['name1', 'name10', 'name2', 'foo20', 'foo10', 'foo9'];
names.sort(); // [ 'foo10', 'foo20', 'foo9', 'name1', 'name10', 'name2' ]
ArrayTools.sortNumberedText(names); // [ 'foo9', 'foo10', 'foo20', 'name1', 'name2', 'name10' ]| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | texts | Yes | string[] | |
| 1 | ignoreCase | No | boolean | true | 
| Return Type | 
|---|
| string[] | 
partition
partition(array: T[], partitionSize: number): T[][]
ArrayTools.partition(array: T[], partitionSize: number): T[][]Breaks an array into smaller arrays of a given size
ArrayTools.partition([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3); // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ], [ 10 ] ]| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | array | Yes | T[] | |
| 1 | partitionSize | No | number | Math.ceil(array.length / 2) | 
| Return Type | 
|---|
| T[][] | 
groupObj
groupObj(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): { [id: string]: T[]; [id: number]: T[]; }
ArrayTools.groupObj(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): { [id: string]: T[]; [id: number]: T[]; }Group items from an array into an object of arrays, based on a given map function.
const arr = [
  { group: 1, name: 'a' },
  { group: 2, name: 'b' },
  { group: 1, name: 'c' },
];
ArrayTools.groupObj(arr, item => item.group); // {
//   1: [ { group: 1, name: 'a' }, { group: 1, name: 'c' } ],
//   2: [ { group: 2, name: 'b' } ]
// }| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | array | Yes | T[] | 
| 1 | mapFn | Yes | (item: T, index: number, arr: T[]) => string \| number | 
| Return Type | 
|---|
| { [id: string]: T[]; [id: number]: T[]; } | 
group
group(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): T[][]
ArrayTools.group(array: T[], mapFn: (item: T, index: number, arr: T[]) => string | number): T[][]Group items from an array into an array of arrays, based on a given map function.
const arr = [
  { group: 1, name: 'a' },
  { group: 2, name: 'b' },
  { group: 1, name: 'c' },
];
ArrayTools.group(arr, item => item.group); // [
//   [ { group: 1, name: 'a' }, { group: 1, name: 'c' } ],
//   [ { group: 2, name: 'b' } ]
// ]| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | array | Yes | T[] | 
| 1 | mapFn | Yes | (item: T, index: number, arr: T[]) => string \| number | 
| Return Type | 
|---|
| T[][] | 
findAndRemove
ArrayTools.findAndRemove(array: T[], predicate: (item: T, index: number, arr: T[]) => any, ...insertItems: T[]): TFind the first item in an array that matches a given predicate, and remove it from the array
Note: This function mutates the provided array
| # | Parameter Name | Required | Type | Description | 
|---|---|---|---|---|
| 0 | array | Yes | T[] | the array to mutate | 
| 1 | predicate | Yes | (item: T, index: number, arr: T[]) => any | a function that returns true/truthy if the item should be removed | 
| 2… | insertItems | No | T[] | items to insert in place of the removed item | 
| Return Type | |
|---|---|
| T | removed item (undefined if not found) | 
findLastAndRemove
ArrayTools.findLastAndRemove(array: T[], predicate: (item: T, index: number, arr: T[]) => any, ...insertItems: T[]): TFind the last item in an array that matches a given predicate, and remove it from the array
Note: This function mutates the provided array
| # | Parameter Name | Required | Type | Description | 
|---|---|---|---|---|
| 0 | array | Yes | T[] | the array to mutate | 
| 1 | predicate | Yes | (item: T, index: number, arr: T[]) => any | a function that returns true/truthy if the item should be removed | 
| 2… | insertItems | No | T[] | items to insert in place of the removed item | 
| Return Type | |
|---|---|
| T | removed item (undefined if not found) | 
filterAndRemove
ArrayTools.filterAndRemove(array: T[], predicate: (item: T, index: number, arr: T[]) => any): T[]Find the items in an array that matches a given predicate, and remove them from the array
Note: This function mutates the provided array
| # | Parameter Name | Required | Type | Description | 
|---|---|---|---|---|
| 0 | array | Yes | T[] | the array to mutate | 
| 1 | predicate | Yes | (item: T, index: number, arr: T[]) => any | a function that returns true/truthy if the item should be removed | 
| Return Type | |
|---|---|
| T[] | removed items | 
utils
ArrayTools.utils;Small helper functions that may help, but aren't important enough to be in ArrayTools directly
isNumString
ArrayTools.utils.isNumString(text: string): booleanReturns true if the given string is a number
| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | text | Yes | string | 
| Return Type | 
|---|
| boolean | 
partitionNums
ArrayTools.utils.partitionNums(ignoreCase: boolean): (name: string) => (string | number)[]Splits a string into an array of strings and numbers
| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | ignoreCase | Yes | boolean | 
| Return Type | 
|---|
| (name: string) => (string \| number)[] | 
ObjectTools
A collection of functions for working with objects
remodel
ObjectTools.remodel(obj: T, func: (entries: [string, V][]) => [string, W][]): OApply a function to the entries of an object
const input = {'foo': 2, 'bar': 1, 'baz': 4}
ObjectTools.remodel(input, (entries) => entries.filter(([k, v]) => v % 2 === 0)) // { foo: 2, baz: 4 }| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | T | 
| 1 | func | Yes | (entries: [string, V][]) => [string, W][] | 
| Return Type | 
|---|
| O | 
remodelEach
ObjectTools.remodelEach(obj: T, func: (entry: [string, V], index: number, entries: [string, V][]) => [string, W]): OApply a function to each of the entries of an object
Note: similar to ObjectTools.map, but the function parameters are different. Prefer ObjectTools.map where possible.
const input = {'foo': 2, 'bar': 1, 'baz': 4}
ObjectTools.remodelEach(input, ([k, v]) => [k, v * 2]) // { foo: 4, bar: 2, baz: 8 }| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | T | 
| 1 | func | Yes | (entry: [string, V], index: number, entries: [string, V][]) => [string, W] | 
| Return Type | 
|---|
| O | 
map
ObjectTools.map(obj: T, func: (key: string, value: V, index: number) => [string, W]): anyMaps the keys and values of an object in a similar way to Array.map
ObjectTools.map({a: 1, b: 2, c: 3}, (key, value) => [key, key + value]); // {a: 'a1', b: 'b2', c: 'c3'}| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | T | 
| 1 | func | Yes | (key: string, value: V, index: number) => [string, W] | 
| Return Type | 
|---|
| any | 
mapValues
ObjectTools.mapValues(obj: T, func: (key: string, value: V, index: number) => W): anyMaps the values of an object in a similar way to Array.map
ObjectTools.map({a: 1, b: 2, c: 3}, (key, value) => key.repeat(value)); // {a: 'a', b: 'bb', c: 'ccc'}| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | T | 
| 1 | func | Yes | (key: string, value: V, index: number) => W | 
| Return Type | 
|---|
| any | 
mapKeys
ObjectTools.mapKeys(obj: T, func: (key: string, value: V, index: number) => string): TMaps the values of an object in a similar way to Array.map
ObjectTools.map({a: 1, b: 2, c: 3}, (key, value) => key.repeat(value)); // {a: 1, bb: 2, ccc: 3}| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | T | 
| 1 | func | Yes | (key: string, value: V, index: number) => string | 
| Return Type | 
|---|
| T | 
filter
ObjectTools.filter(obj: T, func: (key: string, value: V, index: number) => boolean): ORemoves entries from an object based on a predicate function
ObjectTools.filter({a: 1, b: 2, c: 3}, (k, v) => v % 2 === 0) // { b: 2 }| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | T | 
| 1 | func | Yes | (key: string, value: V, index: number) => boolean | 
| Return Type | 
|---|
| O | 
clean
ObjectTools.clean(obj: T): ORemoves properties with undefined values
ObjectTools.clean({a: 1, b: undefined, c: 3}) // { a: 1, c: 3 }| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | T | 
| Return Type | 
|---|
| O | 
invert
ObjectTools.invert(obj: Ti): ToInverts the keys and values of an object
ObjectTools.invert({ a: 'foo', b: 'bar' }); // { foo: 'a', bar: 'b'}| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | obj | Yes | Ti | 
| Return Type | 
|---|
| To | 
StringTools
A collection of string utilities
- StringTools
capitalise
StringTools.capitalise(input: string, forceRestToLowerCase: boolean): stringCapitalises the first letter of each word in a string
StringTools.capitalise('hello world'); // 'Hello World'| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | input | No | string | '' | 
| 1 | forceRestToLowerCase | No | boolean | true | 
| Return Type | 
|---|
| string | 
angloise
StringTools.angloise(input: string): stringRemove accents from a string
StringTools.angloise('éèêë'); // 'eeee'| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | input | Yes | string | 
| Return Type | 
|---|
| string | 
clean
StringTools.clean(input: string): stringRemove accents and non alphanumerics from a string
StringTools.clean('éèêë_--ab0'); // 'eeeeab0'| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | input | No | string | '' | 
| Return Type | 
|---|
| string | 
repeat
StringTools.repeat(maxLength: number, repeated: string): stringRepeat the given string n times
StringTools.repeat(5, '-') // '-----'
StringTools.repeat(1, '-') // '-'
StringTools.repeat(0, '-') // ''
StringTools.repeat(-1, '-') // ''| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | maxLength | Yes | number | 
| 1 | repeated | Yes | string | 
| Return Type | 
|---|
| string | 
makeRegExpSafe
StringTools.makeRegExpSafe(text: string): stringMakes a string safe to use in a RegExp
const textWithSpecChars = '$^*+?.()|{}[]\\';
const longText = `A long line with ${textWithSpecChars} in it`; // 'A long line with $^*+?.()|{}[]\ in it'
const safeText = makeRegExpSafe(textWithSpecChars); // '\$\^\*\+\?\.\(\)\|\{\}\[\]\\'
const regex = new RegExp(safeText);
longText.replace(regex, 'foobar'); // 'A long line with foobar in it'
longText.replace(new RegExp(makeRegExpSafe(textWithSpecChars)), 'foobar'); // 'A long line with foobar in it'| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | text | Yes | string | 
| Return Type | 
|---|
| string | 
replaceAll
StringTools.replaceAll(text: string, searchValue: string | RegExp, replacer: string | ((substring: string, ...args: any[]) => string)): string'Polyfill' replacement for String.prototype.replaceAll, but uses String.prototype.replace (better backwards compatibility)
Accepts a string or RegExp as the searchValue, and a string or function as the replacer.
const input = 'the quick brown fox jumps over the lazy dog';
StringTools.replaceAll(input, /A|E|I|O|U/i, (match) => match.toUpperCase()) // 'thE qUIck brOwn fOx jUmps OvEr thE lAzy dOg'
StringTools.replaceAll(input, /A|E|I|O|U/i, '#') // 'th# q##ck br#wn f#x j#mps #v#r th# l#zy d#g'
StringTools.replaceAll(input, 'o', (match) => match.toUpperCase()) // 'the quick brOwn fOx jumps Over the lazy dOg'
StringTools.replaceAll(input, 'o', '#') // 'the quick br#wn f#x jumps #ver the lazy d#g'| # | Parameter Name | Required | Type | 
|---|---|---|---|
| 0 | text | Yes | string | 
| 1 | searchValue | Yes | string \| RegExp | 
| 2 | replacer | Yes | string \| ((substring: string, ...args: any[]) => string) | 
| Return Type | 
|---|
| string | 
randomId
StringTools.randomId(prefix: string, suffix: string): stringGenerate a random ID.
Provides a random string of 10 alphanumeric characters, with the option to prefix and/or suffix the string.
Note: This is a very simple random ID generator, and is not suitable for use in security contexts, and does not guarantee uniqueness.
StringTools.randomId(); // 'du9876optw'
StringTools.randomId(); // '7xf8kewrkf'
StringTools.randomId(); // 'bums15yb9n'
StringTools.randomId(); // '8tcl55y4u1'
StringTools.randomId(); // '41pxan1bog'
StringTools.randomId(); // '122pa9czh4'
StringTools.randomId(); // 'iu7xappxtz'
StringTools.randomId('foo-'); // 'foo-xpynpfiz06'
StringTools.randomId('', '-bar'); // 'dpyq3i2uwq-bar'
StringTools.randomId('foo-', '-bar'); // 'foo-wapluosnf6-bar'| # | Parameter Name | Required | Type | Default | 
|---|---|---|---|---|
| 0 | prefix | No | string | '' | 
| 1 | suffix | No | string | '' | 
| Return Type | 
|---|
| string | 
clx
clx(...args: ClxType[]): string
StringTools.clx(...args: ClxType[]): string2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago