The iiris
module contains the core functionality of Iiris. It contains
various utility functions that work with a wide variety of data types, while
more specialized functions are stored in separate modules. It is designed to
be imported with a wildcard, e.g.
import * as I from 'iiris'
<T1, T2, R>(fn: VariadicFunction2<T1, T2, R>) => Function2<T1, T2, R>
Create a version of fn
that accepts two arguments.
Note: The returned function is not curried.
const fn = (...args) => args
const wrapped = I.binary(fn)
fn(1, 2, 3)
// => [1, 2, 3]
wrapped(1, 2, 3)
// => [1, 2]
See also: unary
<T extends VariadicFunction0<boolean>>(fn: T) => T
Create a version of a predicate fn
that flips the returned boolean value.
const isZero = (v) => v === 0
const notZero = I.complement(isZero)
notZero(0)
// => false
notZero(1)
// => true
<T extends unknown[], R>(fn: (args: ...T) => R) => (args: ...T) => R
<T extends unknown[], T1, R>(fn1: Function1<T1, R>, fn2: (args: ...T) => T1) => (args: ...T) => R
<T extends unknown[], T1, T2, R>(fn1: Function1<T2, R>, fn2: Function1<T1, T2>, fn3: (args: ...T) => T1) => (args: ...T) => R
Right-to-left function composition.
Note: This function is not curried.
const composed = I.compose(I.add(10), I.multiply(2))
composed(2)
// => 14
<T>(value: T) => () => T
Create a function that always returns value
.
I.map(I.constant(1), [1, 2, 3])
// => [1, 1, 1]
<T extends [unknown, unknown], R>(fn: (args: ...T) => R) => CurriedFunction2<T, R>
Create a curried version of a fn
taking two arguments.
const add = I.curry2((a, b) => a + b)
add(1)(2)
// => 3
add(1, 2)
// => 3
<T extends [unknown, unknown, unknown], R>(fn: (args: ...T) => R) => CurriedFunction3<T, R>
Create a curried version of a fn
taking three arguments.
const add = I.curry3((a, b, c) => a + b + c)
add(1)(2)(3)
// => 6
add(1, 2, 3)
// => 6
<T extends [unknown, unknown, unknown, unknown], R>(fn: (args: ...T) => R) => CurriedFunction4<T, R>
Create a curried version of a fn
taking four arguments.
const add = I.curry4((a, b, c, d) => a + b + c + d)
add(1)(2)(3)(4)
// => 10
add(1, 2, 3, 4)
// => 10
<T, U, R>(fn: Function2<T, U, R>) => Function2<U, T, R>
Flip the arguments of a binary function.
Note: The returned function is not curried.
const fn = (...args) => args
const flipped = I.flip(fn)
flipped(1, 2)
// => [2, 1]
<T>(value: T) => T
Identity function. Returns the first argument.
I.identity(5)
// => 5
() => undefined
Do nothing an return undefined
.
I.map(I.noop, [1, 2, 3])
// => [undefined, undefined, undefined]
(bool: boolean) => boolean
Logical not. Flip the value of a boolean argument
I.not(true)
// => false
I.not(false)
// => true
See also: complement
<T>(initial: T) => T
<T, R>(initial: T, fn1: Function1<T, R>) => R
<T1, T2, R>(initial: T1, fn1: Function1<T1, T2>, fn2: Function1<T2, R>) => R
Pipe an initial
value through one or more functions in left-to-right order,
allowing the programmer to chain operations in a readable manner.
I.pipe(initial, f1, f2, ...fn)
can be thought as syntax sugar for
fn(...(f2(f1(initial))))
Note: This function is not curried.
I.pipe(
[1, 2, 3],
I.map((n) => n * 2),
I.sum
)
// => 12
See also: compose
<T>(fn: (value: T) => void) => (value: T) => T
Create a function that applies fn
to its argument and returns the argument.
Useful for executing a side-effect within a pipeline.
I.pipe(
[1, 2, 3],
I.map(I.multiply(2)),
I.filter(I.gt(2)),
I.tap(console.log),
I.sum
)
// Prints: [ 4, 6 ]
// => 10
<T, R>(fn: VariadicFunction1<T, R>) => Function1<T, R>
Create a version of fn
that accepts a single argument.
const array = [1, 2, 3]
array.map(I.unary(parseInt))
// => [1, 2, 3]
See also: binary
<R>(defaultValue: R) => <T>(fn: (value: T) => R) => (maybeValue: T | undefined) => R
Apply fn
to maybeValue
if it is not undefined
, return defaultValue
otherwise.
I.maybe('', (s) => s.toUpperCase(), 'hi')
// => 'HI'
I.maybe('', (s) => s.toUpperCase(), undefined)
// => ''
See also: valueOr
<T>(defaultValue: T) => (maybeValue: T | undefined) => T
Return maybeValue
if it is not undefined
, defaultValue
otherwise.
I.valueOr(999, 0)
// => 0
I.valueOr(999, undefined)
// => 999
See also: maybe
(n: number) => (m: number) => number
Add two numbers together.
I.map(I.add(1), [1, 2, 3])
// => [2, 3, 4]
(n: number) => number
Decrement a number by 1.
I.map(I.dec, [1, 2, 3])
// => [0, 1, 2]
See also: inc
(divisor: number) => (dividend: number) => number
Divide dividend
by the divisor
.
I.map(I.divideBy(2), [1, 2, 3])
// => [0.5, 1, 1.5]
(n: number) => number
Increment a number by 1.
I.map(I.inc, [1, 2, 3])
// => [2, 3, 4]
(multiplicand: number) => (multiplier: number) => number
Multiply two numbers together.
I.map(I.multiply(2), [1, 2, 3])
// => [2, 4, 6]
(n: number) => number
Return n
with its sign reversed.
I.map(I.negate, [1, 2, 3])
// => [-1, -2, -3]
(subtrahend: number) => (minuend: number) => number
Subtract the subtrahend
from the minuend
.
I.map(I.subtractBy(1), [1, 2, 3])
// => [0, 1, 2]
<T extends Ordered>(array: T[]) => T | undefined
Return the largest element of an array
or undefined
.
I.maximum([1, 2, 3])
// => 3
I.maximum([])
// => undefined
<T, U extends Ordered>(fn: (value: T) => U) => (array: T[]) => T | undefined
Like maximum, but apply fn
to each value before determining their ordering.
const users = [
{ name: 'Alice', age: 10 },
{ name: 'Bob', age: 20 },
{ name: 'Carol', age: 30 },
]
I.maximumBy((u) => u.age, users)
// => { name: 'Carol', age: 30 }
<T extends Ordered>(interval: [lower: T, upper: T]) => (value: T) => T
Clamp a number within the closed interval [lower, upper]
.
I.clamp([0, 10], 5)
// => 5
I.clamp([0, 10], 15)
// => 10
I.clamp([0, 10], -5)
// => 0
<T>(first: T) => (second: T) => boolean
Check if two values are deeply equal.
- Primitive values are compared with SameValueZero.
- Only the own enumerable keys of objects are considered.
- The order of object keys does not matter.
- Built-in objects (e.g. Arrays, Maps & Sets) are not checked for extra keys.
- Sets and Map keys are compared with SameValueZero.
- Error objects are equal if their
name
andmessage
properties are equal. - Functions are compared with
===
. - Supports cyclic references.
- Does not support WeakMaps, WeakSets or typed arrays.
I.equals([1, 2, 3], [1, 2, 3])
// => true
I.equals([1, 2, 3], [4, 5, 6])
// => false
<T, U>(fn: (value: T) => U) => (first: T) => (second: T) => boolean
Like equals, but the function fn
is applied to both values before
determining equality.
I.equalsBy(Math.floor, 1, 1.5)
// => true
See also: equals
<T extends Ordered>(first: T) => (second: T) => boolean
Check if the second
argument is greater than the first
.
Designed to be used as a curried predicate.
I.filter(I.gt(2), [1, 2, 3])
// => [3]
<T extends Ordered>(first: T) => (second: T) => boolean
Check if the second
argument is greater than or equal to the first
.
Designed to be used as a curried predicate.
I.filter(I.gte(2), [1, 2, 3])
// => [2, 3]
<T extends Ordered>(first: T) => (second: T) => boolean
Check if the second
argument is less than the first
.
Designed to be used as a curried predicate.
I.filter(I.lt(2), [1, 2, 3])
// => [1]
<T extends Ordered>(first: T) => (second: T) => boolean
Check if the second
argument is less than or equal to the first
.
Designed to be used as a curried predicate.
I.filter(I.lte(2), [1, 2, 3])
// => [1, 2]
<T extends Ordered>(first: T) => (second: T) => T
Return the larger of two values.
I.max(1, 2)
// => 2
I.max('a', 'b')
// => 'b'
<T, U extends Ordered>(fn: (value: T) => U) => (first: T, second: T) => T
Like max, but apply fn
to both values before determining their ordering.
I.maxBy(Math.abs, 1, -2)
// => -2
<T extends Ordered>(first: T) => (second: T) => T
Return the smaller of two values.
I.min(1, 2)
// => 1
I.min('a', 'b')
// => 'a'
<T, U extends Ordered>(fn: (value: T) => U) => (first: T) => (second: T) => T
Like min, but apply fn
to both values before determining their ordering.
I.minBy(Math.abs, -1, 2)
// => -1
<T, U extends Ordered>(fn: (value: T) => U) => (first: T, second: T) => number
Given a fn
that maps a value
to an Ordered value, create an
ascending comparator function.
Note: The returned function is not curried.
I.sort(I.ascend(I.prop('age')), [{ name: 'Bob' }, { name: 'Alice' }])
// => [{ name: 'Alice' }, { name: 'Bob' }]
See also: descend, sort, sortWith
<T, U extends Ordered>(fn: (value: T) => U) => (first: T, second: T) => number
Given a fn
that maps a value
to an Ordered value, create a
descending comparator function.
Note: The returned function is not curried.
I.sort(I.descend(I.prop('name')), [{ name: 'Alice' }, { name: 'Bob' }])
// => [{ name: 'Bob' }, { name: 'Alice' }]
See also: ascend, sort, sortWith
<T>(value: T | unknown[]) => value is unknown[]
Check if the value
is an
Array.
<T>(value: T | bigint) => value is bigint
Check if the value
is a
BigInt.
<T>(value: T | boolean) => value is boolean
Check if the value
is a
boolean.
<T>(value: Date | T) => value is Date
Check if the value
is a
Date.
<T>(value: T | undefined) => value is T
Check if the value
is not
undefined.
<T>(value: Error | T) => value is Error
Check if the value
is an
Error.
<T>(value: Function | T) => value is Function
Check if the value
is a
function.
<T>(value: Map<unknown, unknown> | T) => value is Map<unknown, unknown>
Check if the value
is a
Map.
<T>(value: T | null | undefined) => value is null | undefined
Check if the value
is
null or
undefined.
<T>(value: T | null) => value is null
Check if the value
is
null.
<T>(value: T | number) => value is number
Check if the value
is a
number.
<T>(value: T | object) => value is object
Check if the value
is an
object.
Note that functions and arrays are also objects.
<T>(value: RegExp | T) => value is RegExp
Check if the value
is a
RegExp.
<T>(value: Set<unknown> | T) => value is Set<unknown>
Check if the value
is a
Set.
<T>(value: T | string) => value is string
Check if the value
is a
string.
<T>(value: T | symbol) => value is symbol
Check if the value
is a
Symbol.
<T>(value: T | undefined) => value is undefined
Check if the value
is
undefined.