Arr
Array utilities for working with readonly and mutable arrays.
Provides functional utilities for array operations including mapping, filtering, type guards, and conversions. Emphasizes immutable operations and type safety.
Import
import { Arr } from '@wollybeard/kit'
import * as Arr from '@wollybeard/kit/arr'
Access
[F]
last
<$T>(array: readonly $T[]): $T | undefined
Parameters:
array
- The array to get the last element from
Returns: The last element, or undefined
if the array is empty
Get the last element of an array.
Examples:
Arr.last([1, 2, 3]) // 3
Arr.last(['a']) // 'a'
Arr.last([]) // undefined
Constants
[C]
empty
readonly[]
DEPRECATED
Use Array.empty from Effect instead
Empty array constant.
Examples:
import { Arr } from '@wollybeard/kit'
const emptyArray = Arr.empty
console.log(emptyArray) // []
[C]
emptyArray
readonly[]
Empty array constant (frozen). Useful as a default value or sentinel.
Examples:
const arr = items ?? Arr.emptyArray
Normalization
[F]
ensure
<$T>(value: $T | $T[]): $T[]
Parameters:
value
- The value to ensure as array
Returns: An array containing the value(s)
Ensure a value is an array. If the value is already an array, return it as-is. Otherwise, wrap it in an array.
Examples:
Arr.ensure('hello') // ['hello']
Arr.ensure(['a', 'b']) // ['a', 'b']
Arr.ensure(42) // [42]
Search
[F]
includes
<$T>(array: $T[], value: unknown): boolean
Parameters:
array
- The array to search invalue
- The unknown value to search for
Returns: True if the value is in the array, with type narrowing
Type-safe array includes check that narrows the type of the value. Unlike the standard includes
, this provides proper type narrowing.
Examples:
const fruits = ['apple', 'banana', 'orange'] as const
const value: unknown = 'apple'
if (Arr.includes(fruits, value)) {
// value is now typed as 'apple' | 'banana' | 'orange'
}
Traits
[C]
Eq
Eq<Any>
Eq trait implementation for immutable arrays.
Provides deep structural equality for readonly arrays by recursively comparing elements using their appropriate Eq implementations.
Examples:
import { Arr } from '@wollybeard/kit'
// Basic array equality
Arr.Eq.is([1, 2, 3], [1, 2, 3]) // true
Arr.Eq.is([1, 2, 3], [1, 2, 4]) // false
Arr.Eq.is([1, 2], [1, 2, 3]) // false (different lengths)
// Nested arrays
Arr.Eq.is(
[[1, 2], [3, 4]],
[[1, 2], [3, 4]],
) // true
// Mixed types
Arr.Eq.is(
[1, 'hello', true],
[1, 'hello', true],
) // true
[C]
Type
Type<Any>
Type trait implementation for immutable arrays.
Provides type checking for readonly array values using Array.isArray.
Examples:
import { Arr } from '@wollybeard/kit'
Arr.Type.is([1, 2, 3]) // true
Arr.Type.is([]) // true
Arr.Type.is('not array') // false
Arr.Type.is(null) // false
Transformation
[F]
transpose
<$T>(rows: readonly(readonly $T[])[]): $T[][]
Parameters:
rows
- The 2D array to transpose
Returns: The transposed 2D array
Transpose a 2D array (convert rows to columns and vice versa). This is a classic matrix transpose operation.
Handles ragged arrays (rows with different lengths) by creating columns that only contain elements from rows that had values at that position.
Examples:
const rows = [
[1, 2, 3],
[4, 5, 6],
]
Arr.transpose(rows)
// [[1, 4], [2, 5], [3, 6]]
const table = [
['Alice', 'Engineer', '100k'],
['Bob', 'Designer', '90k'],
]
Arr.transpose(table)
// [['Alice', 'Bob'], ['Engineer', 'Designer'], ['100k', '90k']]
// Ragged array (uneven row lengths)
const ragged = [[1, 2, 3], [4, 5]]
Arr.transpose(ragged)
// [[1, 4], [2, 5], [3]]
Type Guards
[F]
assert
(value: unknown): void
Parameters:
value
- The value to check
Throws:
- TypeError If the value is not an array
Assert that a value is an array. Throws a TypeError if the value is not an array.
Examples:
function process(value: unknown) {
Arr.assert(value)
// value is now typed as unknown[]
value.forEach(item => console.log(item))
}
Type Utilities
[T]
All
type All<$Tuple extends [...boolean[]]> = $Tuple[number] extends true ? true
: false
Check if all booleans in a tuple are true.
Examples:
type T1 = All<[true, true, true]> // true
type T2 = All<[true, false, true]> // false
[T]
IsTupleMultiple
type IsTupleMultiple<$T> = $T extends [unknown, unknown, ...unknown[]] ? true
: false
Check if a tuple has multiple elements.
Examples:
type T1 = IsTupleMultiple<[1, 2]> // true
type T2 = IsTupleMultiple<[1]> // false
[T]
Push
type Push<$T extends any[], $V> = [...$T, $V]
Push a value onto a tuple.
Examples:
type T = Push<[1, 2], 3> // [1, 2, 3]
[T]
FirstNonUnknownNever
type FirstNonUnknownNever<$T extends any[]> = $T extends
[infer __first__, ...infer __rest__]
? unknown extends __first__
? 0 extends 1 & __first__ ? FirstNonUnknownNever<__rest__> // is any
: FirstNonUnknownNever<__rest__> // is unknown
: __first__ extends never ? FirstNonUnknownNever<__rest__>
: __first__
: never
Get the first non-unknown, non-never element from a tuple.
[T]
EmptyArray
type EmptyArray = typeof emptyArray
Type for the empty array constant.
Other
[T]
Unknown
type Unknown = readonly unknown[]
[T]
Any
type Any = readonly any[]
[T]
Empty
type Empty = readonly []