Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

Array

Works with JavaScript arrays, readonly arrays, and non-empty arrays.

The helpers cover common collection work such as creating arrays, reading elements, transforming values, sorting, grouping, splitting, combining, and reducing many values to one result. Helpers that change contents return new arrays and preserve non-empty array types when the result is guaranteed to contain values.

136 exports Since v2.0.0 Source

Combining

Since v2.0.0

Adds a single element to the end of an iterable, returning a NonEmptyArray.

When to use

Use when you need to guarantee a non-empty result after adding a required trailing value.

See

Signature

declare const append: {
<B>(last: B): <A>(self: Iterable<A>) => [B | A, ...Array<B | A>];
<A, B>(self: Iterable<A>, last: B): [A | B, ...Array<A | B>];
}

Example Appending an element

import { Array } from "effect"
Array.append([1, 2, 3], 4) // => [1, 2, 3, 4]

Concatenates two iterables into a single array.

When to use

Use to combine two iterable inputs into a new array with the second input's elements after the first.

Details

If either input is non-empty, the result is a NonEmptyArray.

See

  • append โ€” add a single element to the end
  • prependAll โ€” add elements to the front

Signature

declare const appendAll: {
<S extends Iterable<any, any, any>, T extends Iterable<any, any, any>>(that: T): (self: S) => OrNonEmpty<S, T, Infer<S> | Infer<T>>;
<A, B>(self: Iterable<A>, that: readonly [B, B]): [A | B, ...Array<A | B>];
<A, B>(self: readonly [A, A], that: Iterable<B>): [A | B, ...Array<A | B>];
<A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>;
}

Example Concatenating arrays

import { Array } from "effect"
Array.appendAll([1, 2], [3, 4]) // => [1, 2, 3, 4]

Computes the cartesian product of two arrays, returning all pairs as tuples.

When to use

Use when you need every [a, b] pair from two arrays as tuples.

Details

Produces every [a, b] combination of an element from self with an element from that, so the result length is self.length * that.length.

See

Signature

declare const cartesian: {
<B>(that: readonly Array<B>): <A>(self: readonly Array<A>) => Array<[A, B]>;
<A, B>(self: readonly Array<A>, that: readonly Array<B>): Array<[A, B]>;
}

Example Generating all pairs from two arrays

import { Array } from "effect"
Array.cartesian([1, 2], ["a", "b"]) // => [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]

Computes the cartesian product of two arrays, applying a combiner to each pair.

When to use

Use to compute every combination from two arrays and immediately transform each pair into a custom result.

Details

Produces every combination of an element from self with an element from that, so the result length is self.length * that.length. Iteration visits every element of that for each element of self.

See

  • cartesian for returning tuples instead of applying a combiner

Signature

declare const cartesianWith: {
<A, B, C>(that: readonly Array<B>, f: (a: A, b: B) => C): (self: readonly Array<A>) => Array<C>;
<A, B, C>(self: readonly Array<A>, that: readonly Array<B>, f: (a: A, b: B) => C): Array<C>;
}

Example Combining numbers and letters

import { Array } from "effect"
Array.cartesianWith([1, 2], ["a", "b"], (a, b) => `${a}-${b}`) // => ["1-a", "1-b", "2-a", "2-b"]
Since v2.0.0

Adds a single element to the front of an iterable, returning a NonEmptyArray.

When to use

Use when you need to guarantee a non-empty result after adding a required leading value.

See

Signature

declare const prepend: {
<B>(head: B): <A>(self: Iterable<A>) => [B | A, ...Array<B | A>];
<A, B>(self: Iterable<A>, head: B): [A | B, ...Array<A | B>];
}

Example Prepending an element

import { Array } from "effect"
Array.prepend([2, 3, 4], 1) // => [1, 2, 3, 4]

Prepends all elements from a prefix iterable to the front of an array.

When to use

Use to prepend multiple elements from an iterable to the front of an array.

Details

If either input is non-empty, the result is a NonEmptyArray.

See

  • prepend โ€” add a single element to the front
  • appendAll โ€” add elements to the end

Signature

declare const prependAll: {
<S extends Iterable<any, any, any>, T extends Iterable<any, any, any>>(that: T): (self: S) => OrNonEmpty<S, T, Infer<S> | Infer<T>>;
<A, B>(self: Iterable<A>, that: readonly [B, B]): [A | B, ...Array<A | B>];
<A, B>(self: readonly [A, A], that: Iterable<B>): [A | B, ...Array<A | B>];
<A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>;
}

Example Prepending multiple elements

import { Array } from "effect"
Array.prependAll([2, 3], [0, 1]) // => [0, 1, 2, 3]

Constructors

Since v2.0.0

Creates a new Array of the specified length with all slots uninitialized.

When to use

Use when you need a pre-sized array that will be filled imperatively.

Details

n is rounded down. NaN and non-positive values are treated as 0. Elements are typed as A | undefined because the slots are empty.

See

  • makeBy โ€” create an array by computing each element

Signature

declare function allocate<A = never>(n: number): Array<A | undefined>

Example Allocating a fixed-size array

import { Array } from "effect"
Array.allocate<number>(3).length // => 3
Since v4.0.0

Exposes the global array constructor.

When to use

Use to access native JavaScript array constructor methods such as isArray or from from the Effect module namespace.

Signature

declare const Array: ArrayConstructor

Example Accessing the Array constructor

import { Array } from "effect"
Array.Array === globalThis.Array // => true
Since v3.2.0

Provides the starting point for the "do simulation" โ€” an array comprehension pattern.

When to use

Use when you want array-comprehension style code with do notation.

Details

Use bind to introduce array variables and let for plain values. Each bind produces the cartesian product of all bound variables, like nested loops. Use filter and map in the pipeline to add conditions and transformations.

See

  • bind โ€” introduce an array variable into the scope
  • bindTo โ€” start a pipeline by naming the first array
  • let โ€” introduce a plain computed value

Signature

declare const Do: ReadonlyArray<{}>

Example Building array comprehensions with do notation

import { Array, pipe } from "effect"
pipe(
Array.Do,
Array.bind("x", () => [1, 3, 5]),
Array.bind("y", () => [2, 4, 6]),
Array.filter(({ x, y }) => x < y),
Array.map(({ x, y }) => [x, y] as const)
) // => [[1, 2], [1, 4], [1, 6], [3, 4], [3, 6], [5, 6]]
Since v2.0.0

Creates an empty array.

When to use

Use to create a typed empty array without allocating placeholder elements.

See

  • of โ€” create a single-element array
  • make โ€” create from multiple values

Signature

declare const empty: <A = never>() => Array<A>

Example Creating an empty array

import { Array } from "effect"
Array.empty<number>() // => []
Since v3.3.0

Normalizes a value that is either a single element or an array into an array.

When to use

Use to normalize input that may be a single value or an array into a consistent array.

Details

If the input is already an array, this returns it by reference. If the input is a single value, this wraps it in a one-element array. This is useful for APIs that accept A | Array<A>.

See

  • of โ€” always wrap in a single-element array
  • fromIterable โ€” convert any iterable

Signature

declare function ensure<A>(self: A | readonly Array<A>): Array<A>

Example Normalizing input

import { Array } from "effect"
Array.ensure("a") // => ["a"]
Array.ensure(["a", "b", "c"]) // => ["a", "b", "c"]

Converts an Iterable to an Array.

When to use

Use to convert any Iterable (Set, Generator, etc.) into an array.

Details

If the input is already an array, this returns it by reference without copying. Otherwise, it creates a new array from the iterable. Use copy if you need a fresh array even when the input is already an array.

See

  • ensure โ€” wrap a single value or return an existing array
  • copy โ€” create a shallow copy of an array

Signature

declare function fromIterable<A>(collection: Iterable<A>): Array<A>

Example Converting a Set to an array

import { Array } from "effect"
Array.fromIterable(new Set([1, 2, 3])) // => [1, 2, 3]
Since v2.0.0

Creates a NonEmptyArray from one or more elements.

When to use

Use when you need to create a typed non-empty array from literal values.

Details

The element type is inferred as the union of all arguments. Because at least one argument is required, this always returns a NonEmptyArray.

See

  • of โ€” create a single-element array
  • fromIterable โ€” create from any iterable

Signature

declare function make<Elements extends [unknown, ...Array<unknown>]>(...elements: Elements): [Elements[number], ...Array<Elements[number]>]

Example Creating an array from values

import { Array } from "effect"
Array.make(1, 2, 3) // => [1, 2, 3]
Since v2.0.0

Creates a NonEmptyArray of length n where element i is computed by f(i).

When to use

Use when you need to compute each array element from its index.

Details

n is rounded down and normalized to an integer greater than or equal to 1. NaN is treated as 1, so this function always returns at least one element. Supports both data-first and data-last usage.

See

  • range โ€” create a range of integers
  • replicate โ€” repeat a single value

Signature

declare const makeBy: {
<A>(f: (i: number) => A): (n: number) => [A, ...Array<A>];
<A>(n: number, f: (i: number) => A): [A, ...Array<A>];
}

Example Generating values from indices

import { Array } from "effect"
Array.makeBy(5, (n) => n * 2) // => [0, 2, 4, 6, 8]
Since v2.0.0

Wraps a single value in a NonEmptyArray.

See

  • make โ€” create from multiple values
  • empty โ€” create an empty array

Signature

declare function of<A>(a: A): [A, ...Array<A>]

Example Creating a single-element array

import { Array } from "effect"
Array.of(1) // => [1]
Since v2.0.0

Creates a NonEmptyArray containing a range of integers, inclusive on both ends.

When to use

Use when you need a non-empty sequence of consecutive integers.

Details

If start > end, returns [start].

See

  • makeBy โ€” generate values from a function

Signature

declare function range(start: number, end: number): [number, ...Array<number>]

Example Creating a range

import { Array } from "effect"
Array.range(1, 3) // => [1, 2, 3]

Creates a NonEmptyArray containing a value repeated n times.

When to use

Use when you need a non-empty array containing repeated copies of one value.

Details

n is normalized to an integer greater than or equal to 1, so this function always returns at least one element. Supports both data-first and data-last usage.

See

  • makeBy โ€” vary values based on index

Signature

declare const replicate: {
(n: number): <A>(a: A) => [A, ...Array<A>];
<A>(a: A, n: number): [A, ...Array<A>];
}

Example Repeating a value

import { Array } from "effect"
Array.replicate("a", 3) // => ["a", "a", "a"]
Since v2.0.0

Builds an array by repeatedly applying a function to a seed value. The function returns Option.some([element, nextSeed]) to continue, or Option.none() to stop.

See

  • makeBy โ€” generate from index
  • range โ€” generate a numeric range

Signature

declare function unfold<B, A>(b: B, f: (b: B) => Option<readonly [A, B]>): Array<A>

Example Generating a sequence

import { Array, Option } from "effect"
Array.unfold(1, (n) => n <= 5 ? Option.some([n, n + 1]) : Option.none()) // => [1, 2, 3, 4, 5]

Converting

Converts a nullable value to an array: null/undefined becomes [], anything else becomes [value].

When to use

Use to treat a nullable single value as zero or one array element.

See

Signature

declare function fromNullishOr<A>(a: A): Array<NonNullable<A>>

Example Converting nullable values to an array

import { Array } from "effect"
Array.fromNullishOr(1) // => [1]
Array.fromNullishOr(null) // => []
Array.fromNullishOr(undefined) // => []

Converts an Option to an array: Some(a) becomes [a], None becomes [].

When to use

Use to convert a single Option into an array for downstream array operations.

See

  • getSomes โ€” extract Some values from an array of Options

Signature

declare const fromOption: <A>(self: Option.Option<A>) => Array<A>

Example Converting an Option to an array

import { Array, Option } from "effect"
Array.fromOption(Option.some(1)) // => [1]
Array.fromOption(Option.none()) // => []

Converts a record into an array of [key, value] tuples.

When to use

Use to convert a record into an array of key-value tuples for iteration or transformation.

Details

Key order follows Object.entries semantics. Empty records produce an empty array.

See

Signature

declare const fromRecord: <K extends string, A>(self: Readonly<Record<K, A>>) => Array<[K, A]>

Example Converting a record to entries

import { Array } from "effect"
Array.fromRecord({ a: 1, b: 2, c: 3 }) // => [["a", 1], ["b", 2], ["c", 3]]

Deduplication

Since v2.0.0

Removes duplicates using Equal.equivalence(), preserving the order of the first occurrence.

When to use

Use to remove repeated values from an iterable when Effect's default equality is the right comparison, preserving the first occurrence.

See

Signature

declare function dedupe<S extends Iterable<any, any, any>>(self: S): S extends readonly [A, A] ? [A, ...Array<A>] : S extends Iterable<A, any, any> ? Array<A> : never

Example Removing duplicates

import { Array } from "effect"
Array.dedupe([1, 2, 1, 3, 2, 4]) // => [1, 2, 3, 4]

Removes consecutive duplicate elements using Equal.equivalence().

When to use

Use when you need to collapse consecutive duplicates while preserving later non-consecutive repeats, and the default equality is sufficient.

See

Signature

declare const dedupeAdjacent: <A>(self: Iterable<A>) => Array<A>

Example Removing adjacent duplicates

import { Array } from "effect"
Array.dedupeAdjacent([1, 1, 2, 2, 3, 3]) // => [1, 2, 3]

Removes consecutive duplicate elements using a custom equivalence.

When to use

Use when consecutive duplicates should be collapsed using a custom equivalence, while equivalent values that appear later should remain in the result.

Details

Non-adjacent duplicates are preserved.

See

Signature

declare const dedupeAdjacentWith: {
<A>(isEquivalent: (self: A, that: A) => boolean): (self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A>;
}

Example Deduplicating adjacent elements

import { Array } from "effect"
Array.dedupeAdjacentWith([1, 1, 2, 2, 3, 3], (a, b) => a === b) // => [1, 2, 3]

Removes duplicates using a custom equivalence, preserving the order of the first occurrence.

When to use

Use to remove all duplicate elements with a custom equivalence when default equality is not appropriate.

See

Signature

declare const dedupeWith: {
<S extends Iterable<any, any, any>>(isEquivalent: (self: Infer<S>, that: Infer<S>) => boolean): (self: S) => With<S, Infer<S>>;
<A>(self: readonly [A, A], isEquivalent: (self: A, that: A) => boolean): [A, ...Array<A>];
<A>(self: Iterable<A>, isEquivalent: (self: A, that: A) => boolean): Array<A>;
}

Example Deduplicating with custom equality

import { Array } from "effect"
Array.dedupeWith([1, 2, 2, 3, 3, 3], (a, b) => a === b) // => [1, 2, 3]

Filtering

Since v2.0.0

Keeps only elements satisfying a predicate (or refinement).

When to use

Use to filter an iterable into a new array of original elements that satisfy a boolean predicate or refinement.

Details

The predicate receives (element, index). Refinements are supported for type narrowing.

See

  • partition โ€” split into matching and non-matching
  • filterMap for transforming while filtering

Signature

declare const filter: {
<A, B>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Array<B>;
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>;
<A, B>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Array<B>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>;
}

Example Filtering even numbers

import { Array } from "effect"
Array.filter([1, 2, 3, 4], (x) => x % 2 === 0) // => [2, 4]

Keeps transformed values for elements where a Filter succeeds.

When to use

Use to filter an iterable with a Result-returning transformation while discarding failures.

Details

The filter receives (element, index). Failures are discarded.

See

  • filter โ€” keep original elements matching a predicate
  • partition for keeping both successes and failures

Signature

declare const filterMap: {
<A, B, X>(f: (input: NoInfer<A>, i: number) => Result<B, X>): (self: Iterable<A>) => Array<B>;
<A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>): Array<B>;
}

Example Filtering and transforming

import { Array, Result } from "effect"
Array.filterMap([1, 2, 3, 4], (n) => n % 2 === 0 ? Result.succeed(n * 10) : Result.failVoid) // => [20, 40]

Extracts all failure values from an iterable of Results, discarding successes.

When to use

Use when you can drop the success channel and only need the failure payloads, not the original result wrappers.

See

Signature

declare function getFailures<T extends Iterable<Result<any, any>, any, any>>(self: T): Array<Failure<Infer<T>>>

Example Extracting failures

import { Array, Result } from "effect"
Array.getFailures([Result.succeed(1), Result.fail("err"), Result.succeed(2)]) // => ["err"]
Since v2.0.0

Extracts all Some values from an iterable of Options, discarding Nones.

When to use

Use to collect only present values from an iterable of Option values while discarding None values.

See

Signature

declare const getSomes: <T extends Iterable<Option.Option<X>>, X = any>(self: T) => Array<Option.Option.Value<ReadonlyArray.Infer<T>>>

Example Extracting Some values

import { Array, Option } from "effect"
Array.getSomes([Option.some(1), Option.none(), Option.some(2)]) // => [1, 2]

Extracts all success values from an iterable of Results, discarding failures.

When to use

Use when you can drop the failure channel and only need the success payloads, not the original result wrappers.

See

  • getFailures โ€” extract failure values
  • separate โ€” split into successes and failures

Signature

declare function getSuccesses<T extends Iterable<Result<any, any>, any, any>>(self: T): Array<Success<Infer<T>>>

Example Extracting successes

import { Array, Result } from "effect"
Array.getSuccesses([Result.succeed(1), Result.fail("err"), Result.succeed(2)]) // => [1, 2]

Splits an iterable using a Filter into successes and failures.

When to use

Use to partition an iterable by evaluating each element with a Result-returning filter and keeping both success and failure values.

Details

Returns [passes, fails]. The filter receives (element, index).

See

  • filter โ€” keep only matching elements
  • filterMap for discarding failures
  • separate โ€” split an iterable of Result values

Signature

declare const partition: {
<A, Pass, Fail>(f: (input: NoInfer<A>, i: number) => Result<Pass, Fail>): (self: Iterable<A>) => [passes: Array<Pass>, fails: Array<Fail>];
<A, Pass, Fail>(self: Iterable<A>, f: (input: A, i: number) => Result<Pass, Fail>): [passes: Array<Pass>, fails: Array<Fail>];
}

Example Partitioning with a filter

import { Array, Result } from "effect"
Array.partition([1, -2, 3], (n, i) =>
n > 0 ? Result.succeed(n + i) : Result.fail(`negative:${n}`)
) // => [[1, 5], ["negative:-2"]]
Since v2.0.0

Separates an iterable of Results into success values and failure values.

When to use

Use to split an iterable of Result values into success and failure arrays.

Details

Returns [successes, failures]. This is equivalent to partition(identity).

See

Signature

declare const separate: <T extends Iterable<Result.Result<any, any>>>(self: T) => [successes: Array<Result.Result.Success<ReadonlyArray.Infer<T>>>, failures: Array<Result.Result.Failure<ReadonlyArray.Infer<T>>>]

Example Separating Results

import { Array, Result } from "effect"
Array.separate([Result.succeed(1), Result.fail("error"), Result.succeed(2)]) // => [[1, 2], ["error"]]

Folding

Since v3.16.0

Computes the number of elements in an iterable that satisfy a predicate.

When to use

Use when you need to count how many elements of an iterable satisfy a predicate.

Details

The predicate receives both the element and its index. Empty iterables return 0.

See

  • filter โ€” when you need the matching elements, not just the count

Signature

declare const countBy: {
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => number;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): number;
}

Example Counting even numbers

import { Array } from "effect"
Array.countBy([1, 2, 3, 4, 5], (n) => n % 2 === 0) // => 2

Returns a Reducer that combines ReadonlyArray values by concatenation.

See

Signature

declare function getReadonlyReducerConcat<A>(): Reducer<readonly Array<A>>
Since v2.0.0

Joins string elements with a separator.

See

  • intersperse โ€” insert separator elements without joining

Signature

declare const join: {
(sep: string): (self: Iterable<string>) => string;
(self: Iterable<string>, sep: string): string;
}

Example Joining strings

import { Array } from "effect"
Array.join(["a", "b", "c"], "-") // => "a-b-c"

Returns a Reducer that combines Array values by concatenation.

See

Signature

declare function makeReducerConcat<A>(): Reducer<Array<A>>
Since v2.0.0

Maps over an array while threading an accumulator through each step, returning both the final state and the mapped array.

When to use

Use when you need to map while threading state through each element and keep the final state.

Details

Combines map and reduce in a single pass. The callback receives the current state, element, and index, and returns [nextState, mappedValue]. The result is [finalState, mappedArray]. This can be used in both data-first and data-last style.

See

  • scan โ€” when you only need the accumulated results (not the final state)
  • reduce โ€” when you only need the final accumulated value

Signature

declare const mapAccum: {
<S, A, B, I extends Iterable<A, any, any> = Iterable<A, any, any>>(s: S, f: (s: S, a: Infer<I>, i: number) => readonly [S, B]): (self: I) => [state: S, mappedArray: With<I, B>];
<S, A, B, I extends Iterable<A, any, any> = Iterable<A, any, any>>(self: I, s: S, f: (s: S, a: Infer<I>, i: number) => readonly [S, B]): [state: S, mappedArray: With<I, B>];
}

Example Running sum alongside mapped values

import { Array } from "effect"
Array.mapAccum([1, 2, 3], 0, (acc, n) => [acc + n, acc + n]) // => [6, [1, 3, 6]]
Since v2.0.0

Folds an iterable from left to right into a single value.

When to use

Use to combine all elements into one accumulated value from left to right.

Details

The function receives (accumulator, element, index).

See

  • reduceRight โ€” fold from right to left
  • scan โ€” fold keeping intermediate values

Signature

declare const reduce: {
<B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Iterable<A>) => B;
<A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B;
}

Example Summing an array

import { Array } from "effect"
Array.reduce([1, 2, 3], 0, (acc, n) => acc + n) // => 6

Folds an iterable from right to left into a single value.

When to use

Use when you need to fold values from right to left.

Details

The function receives (accumulator, element, index).

See

  • reduce โ€” fold from left to right
  • scanRight โ€” fold keeping intermediate values

Signature

declare const reduceRight: {
<B, A>(b: B, f: (b: B, a: A, i: number) => B): (self: Iterable<A>) => B;
<A, B>(self: Iterable<A>, b: B, f: (b: B, a: A, i: number) => B): B;
}

Example Folding from right to left

import { Array } from "effect"
Array.reduceRight([1, 2, 3], 0, (acc, n) => acc + n) // => 6
Since v2.0.0

Folds left-to-right while keeping every intermediate accumulator value.

When to use

Use to compute a running accumulator where each intermediate value is needed.

Details

The output length is input.length + 1 because it starts with the initial value. The result is always a NonEmptyArray. Use reduce if you only need the final accumulated value.

See

  • scanRight โ€” right-to-left scan
  • reduce โ€” fold without intermediate values

Signature

declare const scan: {
<B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => [B, ...Array<B>];
<A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): [B, ...Array<B>];
}

Example Running totals

import { Array } from "effect"
Array.scan([1, 2, 3, 4], 0, (acc, value) => acc + value) // => [0, 1, 3, 6, 10]

Folds right-to-left while keeping every intermediate accumulator value.

When to use

Use to compute a running accumulator from right to left where each intermediate value is needed.

Details

The output length is input.length + 1 because it ends with the initial value. The result is always a NonEmptyArray.

See

  • scan โ€” left-to-right scan
  • reduceRight โ€” fold without intermediate values

Signature

declare const scanRight: {
<B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => [B, ...Array<B>];
<A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): [B, ...Array<B>];
}

Example Scanning running totals in reverse

import { Array } from "effect"
Array.scanRight([1, 2, 3, 4], 0, (acc, value) => acc + value) // => [10, 9, 7, 4, 0]

Getters

Since v2.0.0

Removes the first n elements, creating a new array.

When to use

Use to keep the suffix of an iterable after skipping a fixed number of leading elements.

Details

n is rounded down and clamped to [0, length]. NaN is treated as 0. When n <= 0, this returns a copy of the full array.

See

  • dropRight for removing a fixed number of elements from the end
  • dropWhile for removing a prefix based on a predicate instead of a fixed count
  • take for keeping a fixed number of elements from the start

Signature

declare const drop: {
(n: number): <A>(self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, n: number): Array<A>;
}

Example Dropping from the start

import { Array } from "effect"
Array.drop([1, 2, 3, 4, 5], 2) // => [3, 4, 5]

Removes the last n elements, creating a new array.

When to use

Use to remove the last n elements from an iterable.

Details

n is rounded down and clamped to [0, length]. NaN is treated as 0.

See

  • drop โ€” remove from the start
  • takeRight โ€” keep from the end

Signature

declare const dropRight: {
(n: number): <A>(self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, n: number): Array<A>;
}

Example Dropping from the end

import { Array } from "effect"
Array.dropRight([1, 2, 3, 4, 5], 2) // => [1, 2, 3]

Drops elements from the start while the predicate holds, returning the rest.

When to use

Use to remove a leading prefix of elements that satisfy a predicate.

Details

The predicate receives (element, index).

See

  • takeWhile โ€” keep the matching prefix instead
  • drop โ€” drop a fixed count

Signature

declare const dropWhile: {
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>;
}

Example Dropping while condition holds

import { Array } from "effect"
Array.dropWhile([1, 2, 3, 4, 5], (x) => x < 4) // => [4, 5]

Drops elements from the start while a Filter succeeds.

When to use

Use when you need to drop a prefix from an iterable by computing a Result per element instead of using a simple boolean predicate.

Details

The filter receives (element, index). The result contains the remaining original elements after the first filter failure.

See

Signature

declare const dropWhileFilter: {
<A, B, X>(f: (input: NoInfer<A>, i: number) => Result<B, X>): (self: Iterable<A>) => Array<A>;
<A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>): Array<A>;
}
Since v2.0.0

Reads an element at the given index safely, returning Option.some or Option.none if the index is out of bounds.

When to use

Use when you need to read an array element by index and handle an out-of-bounds index as Option.none.

Details

The index is floored to an integer. This never throws.

See

  • getUnsafe for indexed access that throws when the index is out of bounds
  • head for reading the first element as an Option
  • last for reading the last element as an Option

Signature

declare const get: {
(index: number): <A>(self: readonly Array<A>) => Option<A>;
<A>(self: readonly Array<A>, index: number): Option<A>;
}

Example Accessing indexes safely

import { Array, Option } from "effect"
Array.get([1, 2, 3], 1) // => Option.some(2)
Array.get([1, 2, 3], 10) // => Option.none()

Returns the first element of a NonEmptyReadonlyArray directly (no Option wrapper).

When to use

Use to get the first element without Option wrapping when the array is known to be non-empty.

See

  • head โ€” safe version for possibly-empty arrays

Signature

declare const headNonEmpty: <A>(self: NonEmptyReadonlyArray<A>) => A

Example Getting the head of a non-empty array

import { Array } from "effect"
Array.headNonEmpty([1, 2, 3, 4]) // => 1
Since v2.0.0

Returns all elements except the last safely, wrapped in an Option.

When to use

Use to safely get all elements before the last when the iterable may be empty.

Details

Allocates a new array via slice(0, -1). Empty inputs return Option.none().

See

  • initNonEmpty โ€” when the array is known non-empty
  • tail โ€” all elements except the first

Signature

declare function init<A>(self: Iterable<A>): Option<Array<A>>

Example Getting init

import { Array, Option } from "effect"
Array.init([1, 2, 3, 4]) // => Option.some([1, 2, 3])
Array.init([]) // => Option.none()

Returns all elements except the last of a NonEmptyReadonlyArray.

When to use

Use to get all elements before the last when the array is known to be non-empty.

See

  • init โ€” safe version for possibly-empty arrays
  • tailNonEmpty โ€” all elements except the first

Signature

declare function initNonEmpty<A>(self: readonly [A, A]): Array<A>

Example Getting init of a non-empty array

import { Array } from "effect"
Array.initNonEmpty([1, 2, 3, 4]) // => [1, 2, 3]
Since v2.0.0

Returns the last element of an array safely wrapped in Option.some, or Option.none if the array is empty.

When to use

Use to safely get the last element of an array that may be empty.

See

  • lastNonEmpty โ€” direct access when array is known non-empty
  • head โ€” get the first element

Signature

declare function last<A>(self: readonly Array<A>): Option<A>

Example Getting the last element

import { Array, Option } from "effect"
Array.last([1, 2, 3]) // => Option.some(3)
Array.last([]) // => Option.none()

Returns the last element of a NonEmptyReadonlyArray directly (no Option wrapper).

When to use

Use to get the last element without Option wrapping when the array is known to be non-empty.

See

  • last โ€” safe version for possibly-empty arrays

Signature

declare function lastNonEmpty<A>(self: readonly [A, A]): A

Example Getting the last of a non-empty array

import { Array } from "effect"
Array.lastNonEmpty([1, 2, 3, 4]) // => 4
Since v2.0.0

Returns the number of elements in a ReadonlyArray.

When to use

Use when you need length as a composable function rather than a property access.

Signature

declare function length<A>(self: readonly Array<A>): number

Example Getting the length

import { Array } from "effect"
Array.length([1, 2, 3]) // => 3
Since v2.0.0

Returns the maximum element of a non-empty array according to the given Order.

See

  • min โ€” find the minimum
  • sort โ€” sort the entire array

Signature

declare const max: {
<A>(O: Order<A>): (self: readonly [A, A]) => A;
<A>(self: readonly [A, A], O: Order<A>): A;
}

Example Finding the maximum

import { Array, Order } from "effect"
Array.max([3, 1, 2], Order.Number) // => 3
Since v2.0.0

Returns the minimum element of a non-empty array according to the given Order.

See

  • max โ€” find the maximum
  • sort โ€” sort the entire array

Signature

declare const min: {
<A>(O: Order<A>): (self: readonly [A, A]) => A;
<A>(self: readonly [A, A], O: Order<A>): A;
}

Example Finding the minimum

import { Array, Order } from "effect"
Array.min([3, 1, 2], Order.Number) // => 1
Since v2.0.0

Returns all elements except the first safely, wrapped in an Option.

When to use

Use to safely get all elements after the first when the iterable may be empty.

Details

Allocates a new array via slice(1). Empty inputs return Option.none().

See

  • tailNonEmpty โ€” when the array is known non-empty
  • init โ€” all elements except the last

Signature

declare function tail<A>(self: Iterable<A>): Option<Array<A>>

Example Getting the tail

import { Array, Option } from "effect"
Array.tail([1, 2, 3, 4]) // => Option.some([2, 3, 4])
Array.tail([]) // => Option.none()

Returns all elements except the first of a NonEmptyReadonlyArray.

When to use

Use to get all elements after the first when the array is known to be non-empty.

See

  • tail โ€” safe version for possibly-empty arrays
  • initNonEmpty โ€” all elements except the last

Signature

declare function tailNonEmpty<A>(self: readonly [A, A]): Array<A>

Example Getting the tail of a non-empty array

import { Array } from "effect"
Array.tailNonEmpty([1, 2, 3, 4]) // => [2, 3, 4]
Since v2.0.0

Keeps the first n elements, creating a new array.

When to use

Use to keep up to the first n elements from an iterable as a new array.

Details

n is rounded down and clamped to [0, length]. NaN is treated as 0. Returns an empty array when n <= 0.

See

  • takeRight for keeping elements from the end
  • takeWhile for keeping an initial prefix while a predicate holds
  • drop for removing elements from the start

Signature

declare const take: {
(n: number): <A>(self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, n: number): Array<A>;
}

Example Taking from the start

import { Array } from "effect"
Array.take([1, 2, 3, 4, 5], 3) // => [1, 2, 3]

Keeps the last n elements, creating a new array.

When to use

Use to keep the last n elements of an iterable.

Details

n is rounded down and clamped to [0, length]. NaN is treated as 0. Returns an empty array when n <= 0.

See

  • take โ€” keep from the start
  • dropRight โ€” remove from the end

Signature

declare const takeRight: {
(n: number): <A>(self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, n: number): Array<A>;
}

Example Taking from the end

import { Array } from "effect"
Array.takeRight([1, 2, 3, 4, 5], 3) // => [3, 4, 5]

Takes elements from the start while the predicate holds, stopping at the first element that fails.

When to use

Use to keep the leading elements of an iterable while each element satisfies a predicate, returning the retained prefix as an array.

Details

Supports refinements for type narrowing. The predicate receives (element, index).

See

  • take for keeping a fixed number of leading elements
  • dropWhile for removing the matching prefix and keeping the rest
  • span for splitting the matching prefix from the remaining elements

Signature

declare const takeWhile: {
<A, B>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Array<B>;
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Array<A>;
<A, B>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Array<B>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Array<A>;
}

Example Taking while condition holds

import { Array } from "effect"
Array.takeWhile([1, 3, 2, 4, 1, 2], (x) => x < 4) // => [1, 3, 2]

Takes elements from the start while a Filter succeeds, collecting transformed values.

When to use

Use when you need to take a prefix from an iterable while a function can successfully extract or transform elements, stopping at the first element that produces a failure result.

Details

The filter receives (element, index) and processing stops at the first filter failure.

See

  • takeWhile for taking a prefix based on a boolean predicate

Signature

declare const takeWhileFilter: {
<A, B, X>(f: (input: NoInfer<A>, i: number) => Result<B, X>): (self: Iterable<A>) => Array<B>;
<A, B, X>(self: Iterable<A>, f: (input: NoInfer<A>, i: number) => Result<B, X>): Array<B>;
}

Grouping

Since v2.0.0

Groups consecutive equal elements using Equal.equivalence().

When to use

Use when you already have adjacent equal values and Effect's default equality is the right comparison.

Details

Only adjacent elements are grouped.

See

  • groupWith โ€” use custom equality
  • groupBy โ€” group by a key function into a record

Signature

declare const group: <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<NonEmptyArray<A>>

Example Grouping adjacent equal elements

import { Array } from "effect"
Array.group([1, 1, 2, 2, 2, 3, 1]) // => [[1, 1], [2, 2, 2], [3], [1]]
Since v2.0.0

Groups elements into a record by a key-returning function. Each key maps to a NonEmptyArray of elements that produced that key.

When to use

Use to build buckets of elements indexed by a computed string or symbol key.

Details

Unlike group and groupWith, elements do not need to be adjacent to be grouped together. The key function must return a string or symbol.

Gotchas

When the key function returns a finite union of string literals or unique symbols, the result preserves those keys as optional properties because the input may not produce every key. Open string and symbol key types retain their record index signatures.

See

  • group โ€” group adjacent equal elements
  • groupWith โ€” group adjacent elements by custom equality

Signature

declare const groupBy: {
<A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => GroupByResult<K, [A, ...Array<A>]>;
<A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): GroupByResult<K, [A, ...Array<A>]>;
}

Example Grouping by a property

import { Array } from "effect"
const people = [
{ name: "Alice", group: "A" },
{ name: "Bob", group: "B" },
{ name: "Charlie", group: "A" }
]
Object.keys(Array.groupBy(people, (person) => person.group)).join(",") // => "A,B"

Groups consecutive equal elements using a custom equivalence function.

When to use

Use when you already have a non-empty array arranged so matching elements are adjacent and need a custom equivalence function.

Details

Only adjacent elements are grouped. Non-adjacent duplicates stay separate. Requires a NonEmptyReadonlyArray.

See

  • group for grouping adjacent elements with Equal.equivalence()
  • groupBy for grouping all elements into a record by key, regardless of adjacency

Signature

declare const groupWith: {
<A>(isEquivalent: (self: A, that: A) => boolean): (self: readonly [A, A]) => [[A, ...Array<A>], ...Array<[A, ...Array<A>]>];
<A>(self: readonly [A, A], isEquivalent: (self: A, that: A) => boolean): [[A, ...Array<A>], ...Array<[A, ...Array<A>]>];
}

Example Grouping consecutive equal elements

import { Array } from "effect"
Array.groupWith(
["a", "a", "b", "b", "b", "c", "a"],
(x, y) => x === y
) // => [["a", "a"], ["b", "b", "b"], ["c"], ["a"]]

Guards

Since v2.0.0

Checks whether all elements satisfy the predicate. Supports refinements for type narrowing.

When to use

Use to check whether every array element satisfies a predicate, including refinement-based type narrowing.

See

  • some โ€” test if any element matches

Signature

declare const every: {
<A, B>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: readonly Array<A>) => self is readonly Array<B>;
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: readonly Array<A>) => boolean;
<A, B>(self: readonly Array<A>, refinement: (a: A, i: number) => a is B): self is readonly Array<B>;
<A>(self: readonly Array<A>, predicate: (a: A, i: number) => boolean): boolean;
}

Example Testing all elements

import { Array } from "effect"
Array.every([2, 4, 6], (x) => x % 2 === 0) // => true
Array.every([2, 3, 6], (x) => x % 2 === 0) // => false
Since v2.0.0

Checks whether a value is an Array.

When to use

Use to verify a value is a mutable array, narrowing its type to Array<unknown>.

Details

Acts as a type guard narrowing the input to Array<unknown> and delegates to globalThis.Array.isArray.

See

Signature

declare const isArray: {
(self: unknown): self is Array<unknown>;
<T>(self: T): self is Extract<T, readonly Array<any>>;
}

Example Type-guarding an unknown value

import { Array } from "effect"
Array.isArray(null) // => false
Array.isArray([1, 2, 3]) // => true

Checks whether a mutable Array is empty, narrowing the type to [].

See

Signature

declare function isArrayEmpty<A>(self: Array<A>): self is []

Example Checking for an empty array

import { Array } from "effect"
Array.isArrayEmpty([]) // => true
Array.isArrayEmpty([1, 2, 3]) // => false

Checks whether a mutable Array is non-empty, narrowing the type to NonEmptyArray.

When to use

Use when you need the narrowed value to remain a mutable Array after proving it has at least one element.

See

Signature

declare const isArrayNonEmpty: <A>(self: Array<A>) => self is NonEmptyArray<A>

Example Checking for a non-empty array

import { Array } from "effect"
Array.isArrayNonEmpty([]) // => false
Array.isArrayNonEmpty([1, 2, 3]) // => true

Checks whether a ReadonlyArray is empty, narrowing the type to readonly [].

See

Signature

declare const isReadonlyArrayEmpty: <A>(self: ReadonlyArray<A>) => self is readonly []

Example Checking for an empty readonly array

import { Array } from "effect"
Array.isReadonlyArrayEmpty([]) // => true
Array.isReadonlyArrayEmpty([1, 2, 3]) // => false

Checks whether a ReadonlyArray is non-empty, narrowing the type to NonEmptyReadonlyArray.

When to use

Use when you need to prove a readonly array has at least one element without requiring mutable array methods afterward.

See

Signature

declare const isReadonlyArrayNonEmpty: <A>(self: ReadonlyArray<A>) => self is NonEmptyReadonlyArray<A>

Example Checking for a non-empty readonly array

import { Array } from "effect"
Array.isReadonlyArrayNonEmpty([]) // => false
Array.isReadonlyArrayNonEmpty([1, 2, 3]) // => true
Since v2.0.0

Checks whether at least one element satisfies the predicate. Narrows the type to NonEmptyReadonlyArray on success.

See

  • every โ€” test if all elements match
  • contains โ€” test for a specific value

Signature

declare const some: {
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: readonly Array<A>) => self is readonly [A, A];
<A>(self: readonly Array<A>, predicate: (a: A, i: number) => boolean): self is readonly [A, A];
}

Example Testing for any match

import { Array } from "effect"
Array.some([1, 3, 4], (x) => x % 2 === 0) // => true
Array.some([1, 3, 5], (x) => x % 2 === 0) // => false

Instances

Creates an Equivalence for arrays based on an element Equivalence. Two arrays are equivalent when they have the same length and all elements are pairwise equivalent.

See

  • makeOrder โ€” create an ordering for arrays

Signature

declare const makeEquivalence: <A>(isEquivalent: Equivalence.Equivalence<A>) => Equivalence.Equivalence<ReadonlyArray<A>>

Example Comparing arrays for equality

import { Array } from "effect"
const eq = Array.makeEquivalence<number>((a, b) => a === b)
eq([1, 2, 3], [1, 2, 3]) // => true

Creates an Order for arrays based on an element Order. Arrays are compared element-wise; if all compared elements are equal, shorter arrays come first.

See

Signature

declare const makeOrder: <A>(O: Order.Order<A>) => Order.Order<ReadonlyArray<A>>

Example Comparing arrays

import { Array, Order } from "effect"
const arrayOrder = Array.makeOrder(Order.Number)
arrayOrder([1, 2], [1, 3]) // => -1

Lifting

Lifts a nullable-returning function into one that returns an array: null/undefined becomes [], anything else becomes [value].

See

Signature

declare function liftNullishOr<A extends Array<unknown>, B>(f: (...a: A) => B): (...a: A) => Array<NonNullable<B>>

Example Lifting a nullable function

import { Array } from "effect"
const parseNumber = Array.liftNullishOr((s: string) => {
const n = Number(s)
return isNaN(n) ? null : n
})
parseNumber("123") // => [123]
parseNumber("abc") // => []

Lifts an Option-returning function into one that returns an array: Some(a) becomes [a], None becomes [].

When to use

Use when an optional parser or lookup should participate in array pipelines as zero-or-one results.

See

Signature

declare function liftOption<A extends Array<unknown>, B>(f: (...a: A) => Option<B>): (...a: A) => Array<B>

Example Lifting an Option function

import { Array, Option } from "effect"
const parseNumber = Array.liftOption((s: string) => {
const n = Number(s)
return isNaN(n) ? Option.none() : Option.some(n)
})
parseNumber("123") // => [123]
parseNumber("abc") // => []

Lifts a predicate into an array: returns [value] if the predicate holds, [] otherwise.

See

  • liftOption โ€” lift an Option-returning function

Signature

declare const liftPredicate: {
<A, B>(refinement: Refinement<A, B>): (a: A) => Array<B>;
<A>(predicate: Predicate<A>): <B>(b: B) => Array<B>;
}

Example Wrapping values conditionally

import { Array } from "effect"
const fromEven = Array.liftPredicate((n: number) => n % 2 === 0)
fromEven(1) // => []
fromEven(2) // => [2]

Lifts a Result-returning function into one that returns an array: failures produce [], successes produce [value].

When to use

Use when a fallible parser or lookup should participate in array pipelines as zero-or-one results and the failure value should be discarded.

See

Signature

declare function liftResult<A extends Array<unknown>, E, B>(f: (...a: A) => Result<B, E>): (...a: A) => Array<B>

Example Lifting a Result function

import { Array, Result } from "effect"
const parseNumber = (s: string): Result.Result<number, Error> =>
isNaN(Number(s))
? Result.fail(new Error("Not a number"))
: Result.succeed(Number(s))
const liftedParseNumber = Array.liftResult(parseNumber)
liftedParseNumber("42") // => [42]
liftedParseNumber("not a number") // => []

Mapping

Since v3.2.0

Wraps each array element in an object with the given key, starting a do-notation scope.

When to use

Use when you already have an array and want to start a do-notation pipeline by naming each element.

Details

Equivalent to Array.map(self, (a) => ({ [tag]: a })). This is an alternative to starting with Do plus bind when you already have an array.

See

  • Do โ€” start with an empty scope
  • bind โ€” add another array variable to the scope

Signature

declare const bindTo: {
<N extends string>(tag: N): <A>(self: readonly Array<A>) => Array<{ [K in string]: A }>;
<A, N extends string>(self: readonly Array<A>, tag: N): Array<{ [K in string]: A }>;
}

Example Naming an existing array

import { Array } from "effect"
Array.bindTo([1, 2, 3], "x") // => [{ x: 1 }, { x: 2 }, { x: 3 }]
Since v2.0.0

Applies a function to each suffix of the array (starting from each index), collecting the results.

When to use

Use when you need to compute a result from every suffix of an array, such as cumulative aggregations from each position.

Details

For index i, the function receives self.slice(i).

See

  • scan for keeping intermediate accumulator values during a fold

Signature

declare const extend: {
<A, B>(f: (as: readonly Array<A>) => B): (self: readonly Array<A>) => Array<B>;
<A, B>(self: readonly Array<A>, f: (as: readonly Array<A>) => B): Array<B>;
}

Example Computing suffix lengths

import { Array } from "effect"
Array.extend([1, 2, 3], (as) => as.length) // => [3, 2, 1]
Since v2.0.0

Transforms each element using a function, returning a new array.

When to use

Use to transform each element independently while preserving the array shape.

Details

The function receives (element, index). The return type preserves NonEmptyArray.

See

Signature

declare const map: {
<S extends readonly Array<any>, B>(f: (a: Infer<S>, i: number) => B): (self: S) => With<S, B>;
<S extends readonly Array<any>, B>(self: S, f: (a: Infer<S>, i: number) => B): With<S, B>;
}

Example Doubling values

import { Array } from "effect"
Array.map([1, 2, 3], (x) => x * 2) // => [2, 4, 6]

Models

Since v2.0.0

A mutable array guaranteed to have at least one element.

When to use

Use when mutation is acceptable and non-emptiness must be tracked at the type level.

Details

This is the mutable counterpart of NonEmptyReadonlyArray. Most Array module functions return NonEmptyArray when the result is guaranteed non-empty.

See

Signature

type NonEmptyArray<A> = [A, ...Array<A>]

Example Typing a mutable non-empty array

import type { Array } from "effect"
const nonEmpty: Array.NonEmptyArray<number> = [1, 2, 3]
nonEmpty.push(4)
nonEmpty // => [1, 2, 3, 4]

A readonly array guaranteed to have at least one element.

When to use

Use when non-emptiness must be tracked at the type level while preventing mutation. Many Array module functions accept or return this type.

See

Signature

type NonEmptyReadonlyArray<A> = readonly [A, ...Array<A>]

Example Typing a non-empty array

import type { Array } from "effect"
const nonEmpty: Array.NonEmptyReadonlyArray<number> = [1, 2, 3]
const head: number = nonEmpty[0] // guaranteed to exist
head // => 1

Other

Signature

declare const let: {
<N extends string, B, A extends object>(tag: Exclude<N, keyof A>, f: (a: NoInfer<A>) => B): (self: readonly Array<A>) => Array<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
<N extends string, A extends object, B>(self: readonly Array<A>, tag: Exclude<N, keyof A>, f: (a: NoInfer<A>) => B): Array<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
}

Utility types for working with ReadonlyArray at the type level. Use these to infer element types, preserve non-emptiness, and flatten nested arrays.

Pattern Matching

Since v2.0.0

Pattern-matches on an array, handling empty and non-empty cases separately.

When to use

Use when you need to branch on whether an array is empty.

Details

onNonEmpty receives a NonEmptyReadonlyArray. Supports both data-first and data-last usage.

See

  • matchLeft โ€” destructures into head + tail
  • matchRight โ€” destructures into init + last

Signature

declare const match: {
<B, A, C = B>(options: {
readonly onEmpty: LazyArg<B>;
readonly onNonEmpty: (self: NonEmptyReadonlyArray<A>) => C;
}): (self: readonly Array<A>) => B | C;
<A, B, C = B>(self: readonly Array<A>, options: {
readonly onEmpty: LazyArg<B>;
readonly onNonEmpty: (self: NonEmptyReadonlyArray<A>) => C;
}): B | C;
}

Example Branching on emptiness

import { Array } from "effect"
const describe = Array.match({
onEmpty: () => "empty",
onNonEmpty: ([head, ...tail]) => `head: ${head}, tail: ${tail.length}`
})
describe([]) // => "empty"
describe([1, 2, 3]) // => "head: 1, tail: 2"

Pattern-matches on an array from the left, providing the first element and the remaining elements separately.

When to use

Use when you need to branch on an array and handle the non-empty case as the first element plus the remaining elements.

Details

onNonEmpty receives (head, tail) where tail is the rest of the array.

See

  • match โ€” receives the full non-empty array
  • matchRight โ€” destructures into init + last

Signature

declare const matchLeft: {
<B, A, C = B>(options: {
readonly onEmpty: LazyArg<B>;
readonly onNonEmpty: (head: A, tail: Array<A>) => C;
}): (self: readonly Array<A>) => B | C;
<A, B, C = B>(self: readonly Array<A>, options: {
readonly onEmpty: LazyArg<B>;
readonly onNonEmpty: (head: A, tail: Array<A>) => C;
}): B | C;
}

Example Destructuring head and tail

import { Array } from "effect"
const matchLeft = Array.matchLeft({
onEmpty: () => "empty",
onNonEmpty: (head, tail) => `head: ${head}, tail: ${tail.length}`
})
matchLeft([]) // => "empty"
matchLeft([1, 2, 3]) // => "head: 1, tail: 2"

Pattern-matches on an array from the right, providing all elements except the last and the last element separately.

When to use

Use when you need to branch on an array and handle the non-empty case as the elements before the last plus the last element.

Details

onNonEmpty receives (init, last) where init is everything but the last element.

See

  • match โ€” receives the full non-empty array
  • matchLeft โ€” destructures into head + tail

Signature

declare const matchRight: {
<B, A, C = B>(options: {
readonly onEmpty: LazyArg<B>;
readonly onNonEmpty: (init: Array<A>, last: A) => C;
}): (self: readonly Array<A>) => B | C;
<A, B, C = B>(self: readonly Array<A>, options: {
readonly onEmpty: LazyArg<B>;
readonly onNonEmpty: (init: Array<A>, last: A) => C;
}): B | C;
}

Example Destructuring init and last

import { Array } from "effect"
const matchRight = Array.matchRight({
onEmpty: () => "empty",
onNonEmpty: (init, last) => `init: ${init.length}, last: ${last}`
})
matchRight([]) // => "empty"
matchRight([1, 2, 3]) // => "init: 2, last: 3"

Predicates

Since v2.0.0

Checks whether an array contains a value, using Equal.equivalence() for comparison.

When to use

Use to check whether an iterable contains a value using Effect's default equality instead of providing a comparison function.

See

Signature

declare const contains: {
<A>(a: A): (self: Iterable<A>) => boolean;
<A>(self: Iterable<A>, a: A): boolean;
}

Example Checking membership

import { Array, pipe } from "effect"
pipe(["a", "b", "c", "d"], Array.contains("c")) // => true

Returns a membership-test function using a custom equivalence.

When to use

Use when checking membership with caller-provided equality instead of Equal.equivalence().

See

  • contains for the Equal.equivalence() variant

Signature

declare function containsWith<A>(isEquivalent: (self: A, that: A) => boolean): {
(a: A): (self: Iterable<A>) => boolean;
(self: Iterable<A>, a: A): boolean;
}

Example Checking with custom equality

import { Array, pipe } from "effect"
const containsNumber = Array.containsWith((a: number, b: number) => a === b)
pipe([1, 2, 3, 4], containsNumber(3)) // => true

Searching

Returns the first element matching a predicate, refinement, or mapping function, wrapped in Option.

When to use

Use to scan an iterable in iteration order and return the first selected element or mapped value as an Option.

Details

Accepts a predicate (a, i) => boolean, a refinement, or a function (a, i) => Option<B> for simultaneous find-and-transform. If no element matches, this returns Option.none().

See

Signature

declare const findFirst: {
<A, B>(f: (a: NoInfer<A>, i: number) => Option<B>): (self: Iterable<A>) => Option<B>;
<A, B>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option<B>;
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<A>;
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Option<B>;
<A, B>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option<B>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<A>;
}

Example Finding the first match

import { Array, Option } from "effect"
Array.findFirst([1, 2, 3, 4, 5], (x) => x > 3) // => Option.some(4)

Returns the index of the first element matching the predicate, wrapped in an Option.

When to use

Use to find the index of the first matching element from the start of an iterable.

See

Signature

declare const findFirstIndex: {
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<number>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<number>;
}

Example Finding an index

import { Array, Option } from "effect"
Array.findFirstIndex([5, 3, 8, 9], (x) => x > 5) // => Option.some(2)

Returns the first selected value together with its index, wrapped in an Option.

When to use

Use to find both the first matching element and its index in one pass.

Details

Accepts a predicate, a refinement, or a function returning Option. For an Option-returning function, returns [mappedValue, index] for the first Some, or Option.none() if no element is selected.

See

Signature

declare const findFirstWithIndex: {
<A, B>(f: (a: NoInfer<A>, i: number) => Option<B>): (self: Iterable<A>) => Option<[B, number]>;
<A, B>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option<[B, number]>;
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<[A, number]>;
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Option<[B, number]>;
<A, B>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option<[B, number]>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<[A, number]>;
}

Example Finding element with its index

import { Array, Option } from "effect"
Array.findFirstWithIndex([1, 2, 3, 4, 5], (x) => x > 3) // => Option.some([4, 3])
Since v2.0.0

Returns the last element matching a predicate, refinement, or mapping function, wrapped in Option.

When to use

Use to find the last matching element from the end of an array.

Details

Searches from the end of the array. If no element matches, this returns Option.none().

See

Signature

declare const findLast: {
<A, B>(f: (a: NoInfer<A>, i: number) => Option<B>): (self: Iterable<A>) => Option<B>;
<A, B>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => Option<B>;
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<A>;
<A, B>(self: Iterable<A>, f: (a: A, i: number) => Option<B>): Option<B>;
<A, B>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): Option<B>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<A>;
}

Example Finding the last match

import { Array, Option } from "effect"
Array.findLast([1, 2, 3, 4, 5], (n) => n % 2 === 0) // => Option.some(4)

Returns the index of the last element matching the predicate, wrapped in an Option.

When to use

Use to find the index of the last matching element from the end of an array.

See

Signature

declare const findLastIndex: {
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => Option<number>;
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): Option<number>;
}

Example Finding the last matching index

import { Array, Option } from "effect"
Array.findLastIndex([1, 3, 8, 9], (x) => x < 5) // => Option.some(1)

Sequencing

Since v3.2.0

Adds a new array variable to a do-notation scope, producing the cartesian product with all previous bindings.

When to use

Use to add another array-producing binding to an Array.Do pipeline, pairing each existing scope with every value returned by the callback.

Details

Each bind call adds a named property to the accumulated object. The callback receives the current scope and must return an array. This is equivalent to flatMap plus merging the new value into the scope object.

See

  • Do โ€” start a do-notation pipeline
  • bindTo โ€” name the first array in a pipeline
  • let โ€” add a plain computed value

Signature

declare const bind: {
<A extends object, N extends string, B>(tag: Exclude<N, keyof A>, f: (a: NoInfer<A>) => readonly Array<B>): (self: readonly Array<A>) => Array<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
<A extends object, N extends string, B>(self: readonly Array<A>, tag: Exclude<N, keyof A>, f: (a: NoInfer<A>) => readonly Array<B>): Array<{ [K in string | number | symbol]: K extends keyof A ? A[K] : B }>;
}

Example Binding two arrays

import { Array, pipe } from "effect"
pipe(
Array.Do,
Array.bind("x", () => [1, 2]),
Array.bind("y", () => ["a", "b"])
) // => [{ x: 1, y: "a" }, { x: 1, y: "b" }, { x: 2, y: "a" }, { x: 2, y: "b" }]
Since v2.0.0

Maps each element to an array and flattens the results into a single array.

When to use

Use to map each array element to zero or more values and concatenate the results in one pass.

Details

The function receives (element, index). This returns NonEmptyArray when both the input and mapped arrays are non-empty.

See

  • map โ€” transform without flattening
  • flatten โ€” flatten without mapping

Signature

declare const flatMap: {
<S extends readonly Array<any>, T extends readonly Array<any>>(f: (a: Infer<S>, i: number) => T): (self: S) => AndNonEmpty<S, T, Infer<T>>;
<A, B>(self: readonly [A, A], f: (a: A, i: number) => readonly [B, B]): [B, ...Array<B>];
<A, B>(self: readonly Array<A>, f: (a: A, i: number) => readonly Array<B>): Array<B>;
}

Example Flat mapping an array

import { Array } from "effect"
Array.flatMap([1, 2, 3], (x) => [x, x * 2]) // => [1, 2, 2, 4, 3, 6]

Maps each element with a nullable-returning function, keeping only non-null / non-undefined results.

When to use

Use when you need to map and filter in one step, where the mapper can return null or undefined to skip elements.

See

  • flatMap for mapping each element to an array and flattening
  • fromNullishOr for converting a single nullable value to an array

Signature

declare const flatMapNullishOr: {
<A, B>(f: (a: A) => B): (self: readonly Array<A>) => Array<NonNullable<B>>;
<A, B>(self: readonly Array<A>, f: (a: A) => B): Array<NonNullable<B>>;
}

Example Flat mapping with nullable values

import { Array } from "effect"
Array.flatMapNullishOr([1, 2, 3], (n) => (n % 2 === 0 ? null : n)) // => [1, 3]
Since v2.0.0

Flattens a nested array of arrays into a single array.

When to use

Use to collapse one level of nested arrays when no per-element mapping is needed.

See

  • flatMap โ€” map then flatten in one step

Signature

declare const flatten: <S extends ReadonlyArray<ReadonlyArray<any>>>(self: S) => ReadonlyArray.Flatten<S>

Example Flattening nested arrays

import { Array } from "effect"
Array.flatten([[1, 2], [], [3, 4], [], [5, 6]]) // => [1, 2, 3, 4, 5, 6]

Set Operations

Computes elements in the first array that are not in the second, using Equal.equivalence().

When to use

Use when you need to keep values from the first array that are absent from the second and the default Equal.equivalence() comparison is appropriate.

See

Signature

declare const difference: {
<A>(that: Iterable<A>): (self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, that: Iterable<A>): Array<A>;
}

Example Computing array differences

import { Array } from "effect"
Array.difference([1, 2, 3], [2, 3, 4]) // => [1]

Computes elements in the first array that are not in the second, using a custom equivalence.

When to use

Use when you need to keep only values from the first array and equality must be defined by a custom comparator, such as matching objects by id.

See

  • difference for the Equal.equivalence() variant
  • unionWith for keeping values from either array with custom equality
  • intersectionWith for keeping values present in both arrays with custom equality

Signature

declare function differenceWith<A>(isEquivalent: (self: A, that: A) => boolean): {
(that: Iterable<A>): (self: Iterable<A>) => Array<A>;
(self: Iterable<A>, that: Iterable<A>): Array<A>;
}

Example Computing differences with custom equality

import { Array } from "effect"
Array.differenceWith<number>((a, b) => a === b)([1, 2, 3], [2, 3, 4]) // => [1]

Computes the intersection of two arrays using Equal.equivalence(). Order is determined by the first array.

When to use

Use when Effect equality is the right membership test and you want to keep values present in both inputs while preserving the first input's order.

See

Signature

declare const intersection: {
<B>(that: Iterable<B>): <A>(self: Iterable<A>) => Array<A & B>;
<A, B>(self: Iterable<A>, that: Iterable<B>): Array<A & B>;
}

Example Computing array intersections

import { Array } from "effect"
Array.intersection([1, 2, 3], [3, 4, 1]) // => [1, 3]

Computes the intersection of two arrays using a custom equivalence. Order is determined by the first array.

When to use

Use when you need to keep only values present in both arrays and equality must be defined by a custom comparator, such as matching objects by id.

See

  • intersection for the Equal.equivalence() variant
  • unionWith for keeping values from either array with custom equality
  • differenceWith for keeping values only from the first array with custom equality

Signature

declare function intersectionWith<A>(isEquivalent: (self: A, that: A) => boolean): {
(that: Iterable<A>): (self: Iterable<A>) => Array<A>;
(self: Iterable<A>, that: Iterable<A>): Array<A>;
}

Example Computing intersections with custom equality

import { Array } from "effect"
const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
const array2 = [{ id: 3 }, { id: 4 }, { id: 1 }]
const isEquivalent = (a: { id: number }, b: { id: number }) => a.id === b.id
Array.intersectionWith(isEquivalent)(array2)(array1) // => [{ id: 1 }, { id: 3 }]
Since v2.0.0

Computes the union of two arrays, removing duplicates using Equal.equivalence().

See

Signature

declare const union: {
<T extends Iterable<any, any, any>>(that: T): <S extends Iterable<any, any, any>>(self: S) => OrNonEmpty<S, T, Infer<S> | Infer<T>>;
<A, B>(self: readonly [A, A], that: readonly Array<B>): [A | B, ...Array<A | B>];
<A, B>(self: readonly Array<A>, that: readonly [B, B]): [A | B, ...Array<A | B>];
<A, B>(self: Iterable<A>, that: Iterable<B>): Array<A | B>;
}

Example Computing array unions

import { Array } from "effect"
Array.union([1, 2], [2, 3]) // => [1, 2, 3]

Computes the union of two arrays using a custom equivalence, removing duplicates.

When to use

Use when you need the union of two arrays but duplicate detection must use a custom equivalence instead of the default Equal.equivalence().

See

Signature

declare const unionWith: {
<S extends Iterable<any, any, any>, T extends Iterable<any, any, any>>(that: T, isEquivalent: (self: Infer<S>, that: Infer<T>) => boolean): (self: S) => OrNonEmpty<S, T, Infer<S> | Infer<T>>;
<A, B>(self: readonly [A, A], that: Iterable<B>, isEquivalent: (self: A, that: B) => boolean): [A | B, ...Array<A | B>];
<A, B>(self: Iterable<A>, that: readonly [B, B], isEquivalent: (self: A, that: B) => boolean): [A | B, ...Array<A | B>];
<A, B>(self: Iterable<A>, that: Iterable<B>, isEquivalent: (self: A, that: B) => boolean): Array<A | B>;
}

Example Computing unions with custom equality

import { Array } from "effect"
Array.unionWith([1, 2], [2, 3], (a, b) => a === b) // => [1, 2, 3]

Sorting

Since v2.0.0

Sorts an array by the given Order, returning a new array.

When to use

Use to sort an array using a single Order comparator.

Details

Preserves NonEmptyArray in the return type. Use sortWith to sort by a derived key, or sortBy for multi-key sorting.

See

  • sortWith โ€” sort by a mapping function
  • sortBy โ€” sort by multiple orders

Signature

declare const sort: {
<B>(O: Order<B>): <A, S extends Iterable<A, any, any>>(self: S) => With<S, Infer<S>>;
<A, B>(self: readonly [A, A], O: Order<B>): [A, ...Array<A>];
<A, B>(self: Iterable<A>, O: Order<B>): Array<A>;
}

Example Sorting numbers

import { Array, Order } from "effect"
Array.sort([3, 1, 4, 1, 5], Order.Number) // => [1, 1, 3, 4, 5]
Since v2.0.0

Sorts an array by multiple Orders applied in sequence: the first order is used first; ties are broken by the second order, and so on.

When to use

Use to sort by multiple criteria where later orders break ties from earlier ones.

Details

This is data-last only and returns a function. The return type preserves NonEmptyArray.

See

  • sort โ€” sort by a single Order
  • sortWith โ€” sort by a derived key

Signature

declare function sortBy<S extends Iterable<any, any, any>>(...orders: readonly Array<Order<Infer<S>>>): (self: S) => S extends readonly [A, A] ? [A, ...Array<A>] : S extends Iterable<A, any, any> ? Array<A> : never

Example Sorting by multiple keys

import { Array, Order, pipe } from "effect"
const users = [
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Charlie", age: 30 }
]
const sortedUsers = pipe(
users,
Array.sortBy(
Order.mapInput(Order.Number, (user: (typeof users)[number]) => user.age),
Order.mapInput(Order.String, (user: (typeof users)[number]) => user.name)
)
)
sortedUsers.map((user) => user.name).join(",") // => "Bob,Alice,Charlie"
Since v2.0.0

Sorts an array by a derived key using a mapping function and an Order for that key.

When to use

Use when you need to sort values by a derived key, such as a string length or object field, while keeping the original values.

Details

Equivalent to sort(Order.mapInput(order, f)), but more convenient.

See

  • sort for sorting with an Order that compares the elements directly
  • sortBy for sorting with multiple Orders applied in sequence

Signature

declare const sortWith: {
<S extends Iterable<any, any, any>, B>(f: (a: Infer<S>) => B, order: Order<B>): (self: S) => With<S, Infer<S>>;
<A, B>(self: readonly [A, A], f: (a: A) => B, O: Order<B>): [A, ...Array<A>];
<A, B>(self: Iterable<A>, f: (a: A) => B, order: Order<B>): Array<A>;
}

Example Sorting strings by length

import { Array, Order } from "effect"
Array.sortWith(["aaa", "b", "cc"], (s) => s.length, Order.Number) // => ["b", "cc", "aaa"]

Splitting

Since v2.0.0

Applies a function repeatedly to consume prefixes of the array and collect the values it produces.

When to use

Use when you need custom grouping logic where each step returns both a value and the remaining input.

Details

The function receives a NonEmptyReadonlyArray and returns [value, rest]. Processing continues until the remaining array is empty.

See

  • chunksOf โ€” split into fixed-size chunks
  • splitAt โ€” split at an index

Signature

declare const chop: {
<S extends Iterable<any, any, any>, B>(f: (as: readonly [Infer<S>, Infer<S>]) => readonly [B, readonly Array<Infer<S>>]): (self: S) => With<S, Infer<S>>;
<A, B>(self: readonly [A, A], f: (as: readonly [A, A]) => readonly [B, readonly Array<A>]): [B, ...Array<B>];
<A, B>(self: Iterable<A>, f: (as: readonly [A, A]) => readonly [B, readonly Array<A>]): Array<B>;
}

Example Chopping an array

import { Array } from "effect"
Array.chop([1, 2, 3, 4, 5], (as): [number, Array<number>] => [as[0] * 2, as.slice(1)]) // => [2, 4, 6, 8, 10]
Since v2.0.0

Splits an iterable into chunks of length n. The last chunk may be shorter if n does not evenly divide the length.

When to use

Use to divide an iterable into a new array of non-overlapping chunks with a maximum chunk size.

Details

n is rounded down and normalized to at least 1; NaN and non-positive values therefore produce singleton chunks. chunksOf(n)([]) is [], not [[]]. Each chunk is a NonEmptyArray, and the outer return type preserves NonEmptyArray.

See

  • split โ€” split into a given number of groups
  • window โ€” sliding windows

Signature

declare const chunksOf: {
(n: number): <S extends Iterable<any, any, any>>(self: S) => With<S, [Infer<S>, ...Array<Infer<S>>]>;
<A>(self: readonly [A, A], n: number): [[A, ...Array<A>], ...Array<[A, ...Array<A>]>];
<A>(self: Iterable<A>, n: number): Array<[A, ...Array<A>]>;
}

Example Chunking an array

import { Array } from "effect"
Array.chunksOf([1, 2, 3, 4, 5], 2) // => [[1, 2], [3, 4], [5]]
Since v2.0.0

Splits an iterable into two arrays: the longest prefix where the predicate holds, and the remaining elements.

When to use

Use when you need both the longest predicate-matching prefix and the remaining elements.

Details

Equivalent to [takeWhile(pred), dropWhile(pred)], but more efficient because it runs in a single pass. Supports refinements for type narrowing of the prefix.

See

  • takeWhile for keeping only the matching prefix
  • dropWhile for keeping only the elements after the matching prefix
  • splitWhere for splitting at the first element that satisfies a predicate

Signature

declare const span: {
<A, B>(refinement: (a: NoInfer<A>, i: number) => a is B): (self: Iterable<A>) => [init: Array<B>, rest: Array<Exclude<A, B>>];
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => [init: Array<A>, rest: Array<A>];
<A, B>(self: Iterable<A>, refinement: (a: A, i: number) => a is B): [init: Array<B>, rest: Array<Exclude<A, B>>];
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [init: Array<A>, rest: Array<A>];
}

Example Splitting at predicate boundary

import { Array } from "effect"
Array.span([1, 3, 2, 4, 5], (x) => x % 2 === 1) // => [[1, 3], [2, 4, 5]]
Since v2.0.0

Splits an iterable into n roughly equal-sized chunks.

When to use

Use to distribute elements across a fixed number of groups, such as when splitting work across threads.

Details

n is rounded down and normalized to at least 1, with NaN treated as 1. The last chunk may be shorter.

See

  • chunksOf โ€” split into fixed-size chunks

Signature

declare const split: {
(n: number): <A>(self: Iterable<A>) => Array<Array<A>>;
<A>(self: Iterable<A>, n: number): Array<Array<A>>;
}

Example Splitting into groups

import { Array } from "effect"
Array.split([1, 2, 3, 4, 5, 6, 7, 8], 3) // => [[1, 2, 3], [4, 5, 6], [7, 8]]
Since v2.0.0

Splits an iterable into two arrays at the given index.

When to use

Use to divide an array into a prefix and suffix at a specific position.

Details

n is rounded down and clamped to [0, length]. NaN is treated as 0, which places all elements in the second array.

See

Signature

declare const splitAt: {
(n: number): <A>(self: Iterable<A>) => [beforeIndex: Array<A>, fromIndex: Array<A>];
<A>(self: Iterable<A>, n: number): [beforeIndex: Array<A>, fromIndex: Array<A>];
}

Example Splitting at an index

import { Array } from "effect"
Array.splitAt([1, 2, 3, 4, 5], 3) // => [[1, 2, 3], [4, 5]]

Splits a non-empty array into two parts at the given index. The first part is guaranteed to be non-empty (n is clamped to >= 1).

When to use

Use when downstream code requires the left side of the split to contain at least one element.

Details

n is rounded down and clamped to [1, length]. NaN is treated as 1.

See

  • splitAt โ€” for possibly-empty arrays

Signature

declare const splitAtNonEmpty: {
(n: number): <A>(self: readonly [A, A]) => [beforeIndex: [A, ...Array<A>], fromIndex: Array<A>];
<A>(self: readonly [A, A], n: number): [beforeIndex: [A, ...Array<A>], fromIndex: Array<A>];
}

Example Splitting a non-empty array

import { Array } from "effect"
Array.splitAtNonEmpty(["a", "b", "c", "d", "e"], 3) // => [["a", "b", "c"], ["d", "e"]]

Splits an iterable at the first element matching the predicate. The matching element is included in the second array.

When to use

Use when you need to split an array at the first element that marks a condition boundary.

See

  • span โ€” splits at the first element that fails the predicate
  • splitAt โ€” split at a fixed index

Signature

declare const splitWhere: {
<A>(predicate: (a: NoInfer<A>, i: number) => boolean): (self: Iterable<A>) => [beforeMatch: Array<A>, fromMatch: Array<A>];
<A>(self: Iterable<A>, predicate: (a: A, i: number) => boolean): [beforeMatch: Array<A>, fromMatch: Array<A>];
}

Example Splitting at a condition

import { Array } from "effect"
Array.splitWhere([1, 2, 3, 4, 5], (n) => n > 3) // => [[1, 2, 3], [4, 5]]
Since v2.0.0

Splits a non-empty array into all elements except the last, and the last element.

When to use

Use when you need to split a non-empty array into the elements before the last element and the last element.

Details

Returns a tuple [init, last] and requires a NonEmptyReadonlyArray.

See

  • unprepend for splitting a non-empty array into head and tail
  • initNonEmpty for getting only the elements before the last
  • lastNonEmpty for getting only the last element

Signature

declare function unappend<A>(self: readonly [A, A]): [arrayWithoutLastElement: Array<A>, lastElement: A]

Example Destructuring init and last

import { Array } from "effect"
Array.unappend([1, 2, 3, 4]) // => [[1, 2, 3], 4]

Splits a non-empty array into its first element and the remaining elements.

When to use

Use when you have a NonEmptyReadonlyArray and need both its first element and the remaining elements as separate values.

Details

Returns a tuple [head, tail] and requires a NonEmptyReadonlyArray.

See

  • unappend for splitting a non-empty array into init and last
  • headNonEmpty for getting only the first element
  • tailNonEmpty for getting only the elements after the first

Signature

declare function unprepend<A>(self: readonly [A, A]): [firstElement: A, remainingElements: Array<A>]

Example Destructuring head and tail

import { Array } from "effect"
Array.unprepend([1, 2, 3, 4]) // => [1, [2, 3, 4]]
Since v3.13.2

Creates overlapping sliding windows of size n.

When to use

Use to process sequences with a moving window, such as for computing running averages or detecting patterns.

Details

n is rounded down, with NaN and non-positive values treated as 0. Returns an empty array if the normalized size is 0 or exceeds the array length. Each window is a tuple of exactly the normalized size.

See

  • chunksOf โ€” non-overlapping chunks

Signature

declare const window: {
<N extends number>(n: N): <A>(self: Iterable<A>) => Array<TupleOf<N, A>>;
<A, N extends number>(self: Iterable<A>, n: N): Array<TupleOf<N, A>>;
}

Example Creating sliding windows

import { Array } from "effect"
const values = [1, 2, 3, 4, 5]
Array.window(values, 3) // => [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
Array.window(values, 6) // => []

Transforming

Since v2.0.0

Creates a shallow copy of an array.

When to use

Use to create a distinct array reference for an existing array, for example before mutating the returned array.

Details

The return type preserves NonEmptyArray. Use this when you need a distinct reference, for example before mutating the returned array.

See

  • fromIterable โ€” returns the same reference for arrays

Signature

declare const copy: {
<A>(self: readonly [A, A]): [A, ...Array<A>];
<A>(self: readonly Array<A>): Array<A>;
}

Example Copying an array

import { Array } from "effect"
const original = [1, 2, 3]
const copied = Array.copy(original)
copied // => [1, 2, 3]
original === copied // => false
Since v2.0.0

Inserts an element at the specified index safely, returning a new NonEmptyArray wrapped in an Option.

When to use

Use to insert a single element at a specific position in an array.

Details

Valid indices are 0 to length, inclusive. Inserting at length appends.

See

  • replace โ€” replace an existing element
  • modify โ€” transform an element at an index

Signature

declare const insertAt: {
<B>(i: number, b: B): <A>(self: Iterable<A>) => Option<[B | A, ...Array<B | A>]>;
<A, B>(self: Iterable<A>, i: number, b: B): Option<[A | B, ...Array<A | B>]>;
}

Example Inserting at an index

import { Array, Option } from "effect"
Array.insertAt(["a", "b", "c", "e"], 3, "d") // => Option.some(["a", "b", "c", "d", "e"])

Places a separator element between every pair of elements.

When to use

Use to insert a separator between elements, for example when preparing data for display or concatenation.

Details

The return type preserves NonEmptyArray. Empty inputs produce an empty result.

See

  • join โ€” intersperse and join into a string

Signature

declare const intersperse: {
<B>(middle: B): <S extends Iterable<any, any, any>>(self: S) => With<S, B | Infer<S>>;
<A, B>(self: readonly [A, A], middle: B): [A | B, ...Array<A | B>];
<A, B>(self: Iterable<A>, middle: B): Array<A | B>;
}

Example Interspersing a separator

import { Array } from "effect"
Array.intersperse([1, 2, 3], 0) // => [1, 0, 2, 0, 3]
Since v2.0.0

Applies a function to the element at the specified index safely, returning the updated array in Option.some.

When to use

Use to derive a replacement value from an array element at a specific index while leaving the other elements unchanged.

Details

Returns Option.none() when the index is out of bounds.

See

Signature

declare const modify: {
<A, B, S extends Iterable<A, any, any> = Iterable<A, any, any>>(i: number, f: (a: Infer<S>) => B): (self: S) => Option<With<S, B | Infer<S>>>;
<A, B, S extends Iterable<A, any, any> = Iterable<A, any, any>>(self: S, i: number, f: (a: Infer<S>) => B): Option<With<S, B | Infer<S>>>;
}

Example Modifying an element

import { Array, Option } from "effect"
const values = [1, 2, 3, 4]
const double = (n: number) => n * 2
Array.modify(values, 2, double) // => Option.some([1, 2, 6, 4])
Array.modify(values, 5, double) // => Option.none()

Applies a function to the first element of a non-empty array, returning a new array.

When to use

Use to transform the first element of a non-empty array while preserving the rest.

See

Signature

declare const modifyHeadNonEmpty: {
<A, B>(f: (a: A) => B): (self: readonly [A, A]) => [A | B, ...Array<A | B>];
<A, B>(self: readonly [A, A], f: (a: A) => B): [A | B, ...Array<A | B>];
}

Example Modifying the head

import { Array } from "effect"
Array.modifyHeadNonEmpty([1, 2, 3], (n) => n * 10) // => [10, 2, 3]

Applies a function to the last element of a non-empty array, returning a new array.

When to use

Use when you already know the array is non-empty and the new last element depends on the current last element.

See

Signature

declare const modifyLastNonEmpty: {
<A, B>(f: (a: A) => B): (self: readonly [A, A]) => [A | B, ...Array<A | B>];
<A, B>(self: readonly [A, A], f: (a: A) => B): [A | B, ...Array<A | B>];
}

Example Modifying the last element

import { Array } from "effect"
Array.modifyLastNonEmpty([1, 2, 3], (n) => n * 2) // => [1, 2, 6]
Since v3.8.4

Pads or truncates an array to exactly n elements, filling with fill if the array is shorter, or slicing if longer.

When to use

Use to ensure an array has a specific length, padding with a fill value or truncating as needed.

Details

n is rounded down. NaN and non-positive values are treated as 0, which returns an empty array.

See

  • take โ€” truncate without padding
  • replicate โ€” create an array of a single repeated value

Signature

declare const pad: {
<A, T>(n: number, fill: T): (self: Array<A>) => Array<A | T>;
<A, T>(self: Array<A>, n: number, fill: T): Array<A | T>;
}

Example Padding an array

import { Array } from "effect"
Array.pad([1, 2, 3], 6, 0) // => [1, 2, 3, 0, 0, 0]
Since v2.0.0

Removes the element at the specified index, returning a new array. If the index is out of bounds, returns a copy of the original.

When to use

Use when you want a missing index to be a no-op and need a fresh array result instead of an optional failure.

See

  • insertAt โ€” insert an element
  • filter โ€” remove elements by predicate

Signature

declare const remove: {
(i: number): <A>(self: Iterable<A>) => Array<A>;
<A>(self: Iterable<A>, i: number): Array<A>;
}

Example Removing an element

import { Array } from "effect"
Array.remove([1, 2, 3, 4], 2) // => [1, 2, 4]
Array.remove([1, 2, 3, 4], 5) // => [1, 2, 3, 4]
Since v2.0.0

Replaces the element at the specified index safely with a new value, returning the updated array in Option.some.

When to use

Use to set a fixed replacement value at a specific index.

Details

Returns Option.none() when the index is out of bounds.

See

  • modify โ€” transform an element with a function
  • insertAt โ€” insert without removing

Signature

declare const replace: {
<B>(i: number, b: B): <A, S extends Iterable<A, any, any> = Iterable<A, any, any>>(self: S) => Option<With<S, B | Infer<S>>>;
<A, B, S extends Iterable<A, any, any> = Iterable<A, any, any>>(self: S, i: number, b: B): Option<With<S, B | Infer<S>>>;
}

Example Replacing an element

import { Array, Option } from "effect"
Array.replace([1, 2, 3], 1, 4) // => Option.some([1, 4, 3])
Since v2.0.0

Reverses an iterable into a new array.

When to use

Use to reverse an iterable into a new array without mutating the original input.

Details

Preserves NonEmptyArray in the return type.

Signature

declare function reverse<S extends Iterable<any, any, any>>(self: S): S extends readonly [A, A] ? [A, ...Array<A>] : S extends Iterable<A, any, any> ? Array<A> : never

Example Reversing an array

import { Array } from "effect"
Array.reverse([1, 2, 3, 4]) // => [4, 3, 2, 1]
Since v2.0.0

Transforms an array by rotating it n steps. Positive n rotates right; negative n rotates left.

When to use

Use when elements should wrap around the end of the array rather than being dropped.

Details

n is rounded to the nearest integer before rotating. The return type preserves NonEmptyArray. Empty arrays, or rotations normalized to 0, return a copy.

See

  • take for taking a fixed number of elements from the start
  • drop for dropping a fixed number of elements from the start

Signature

declare const rotate: {
(n: number): <S extends Iterable<any, any, any>>(self: S) => With<S, Infer<S>>;
<A>(self: readonly [A, A], n: number): [A, ...Array<A>];
<A>(self: Iterable<A>, n: number): Array<A>;
}

Example Rotating elements

import { Array } from "effect"
Array.rotate(["a", "b", "c", "d"], 2) // => ["c", "d", "a", "b"]

Replaces the first element of a non-empty array with a new value.

When to use

Use when you already know the array is non-empty and the replacement value does not depend on the current first element.

See

Signature

declare const setHeadNonEmpty: {
<B>(b: B): <A>(self: readonly [A, A]) => [B | A, ...Array<B | A>];
<A, B>(self: readonly [A, A], b: B): [A | B, ...Array<A | B>];
}

Example Setting the head

import { Array } from "effect"
Array.setHeadNonEmpty([1, 2, 3], 10) // => [10, 2, 3]

Replaces the last element of a non-empty array with a new value.

When to use

Use when you already know the array is non-empty and the replacement value does not depend on the current last element.

See

Signature

declare const setLastNonEmpty: {
<B>(b: B): <A>(self: readonly [A, A]) => [B | A, ...Array<B | A>];
<A, B>(self: readonly [A, A], b: B): [A | B, ...Array<A | B>];
}

Example Setting the last element

import { Array } from "effect"
Array.setLastNonEmpty([1, 2, 3], 4) // => [1, 2, 4]

Traversing

Since v2.0.0

Runs a side-effect for each element. The callback receives (element, index).

When to use

Use to iterate over an array for side-effects only, when no transformed result is needed.

See

  • map for transforming each element into a new array

Signature

declare const forEach: {
<A>(f: (a: A, i: number) => void): (self: Iterable<A>) => void;
<A>(self: Iterable<A>, f: (a: A, i: number) => void): void;
}

Example Iterating with side-effects

import { Array } from "effect"
const visited: Array<number> = []
Array.forEach([1, 2, 3], (n) => visited.push(n))
visited // => [1, 2, 3]

Unsafe

Reads an element at the given index, throwing if the index is out of bounds.

When to use

Use to read an array element at a known valid index when out-of-bounds would be a programming error.

Details

Throws an Error with the message "Index out of bounds: <i>". Prefer get for safe access.

See

  • get โ€” safe version returning Option

Signature

declare const getUnsafe: {
(index: number): <A>(self: readonly Array<A>) => A;
<A>(self: readonly Array<A>, index: number): A;
}

Example Accessing indexes unsafely

import { Array } from "effect"
Array.getUnsafe([1, 2, 3], 1) // => 2
// Array.getUnsafe([1, 2, 3], 10) // throws Error

Utility Types

Since v2.0.0

Type lambda for ReadonlyArray, used for higher-kinded type operations.

Signature

interface ReadonlyArrayTypeLambda extends TypeLambda {
readonly type: readonly Array<unknown>;
}

Zipping

Since v2.0.0

Splits an array of pairs into two arrays. Inverse of zip.

See

  • zip โ€” combine two arrays into pairs

Signature

declare const unzip: <S extends Iterable<readonly [any, any]>>(self: S) => S extends NonEmptyReadonlyArray<readonly [infer A, infer B]> ? [NonEmptyArray<A>, NonEmptyArray<B>] : S extends Iterable<readonly [infer A, infer B]> ? [Array<A>, Array<B>] : never

Example Unzipping pairs

import { Array } from "effect"
Array.unzip([[1, "a"], [2, "b"], [3, "c"]]) // => [[1, 2, 3], ["a", "b", "c"]]
Since v2.0.0

Pairs elements from two iterables by position. If the iterables differ in length, the extra elements from the longer one are discarded.

When to use

Use when you need simple pairs of corresponding elements from two iterables.

Details

Returns NonEmptyArray when both inputs are non-empty.

See

  • zipWith โ€” zip with a combiner function
  • unzip โ€” inverse operation

Signature

declare const zip: {
<B>(that: readonly [B, B]): <A>(self: readonly [A, A]) => [[A, B], ...Array<[A, B]>];
<B>(that: Iterable<B>): <A>(self: Iterable<A>) => Array<[A, B]>;
<A, B>(self: readonly [A, A], that: readonly [B, B]): [[A, B], ...Array<[A, B]>];
<A, B>(self: Iterable<A>, that: Iterable<B>): Array<[A, B]>;
}

Example Zipping two arrays

import { Array } from "effect"
Array.zip([1, 2, 3], ["a", "b"]) // => [[1, "a"], [2, "b"]]
Since v2.0.0

Combines elements from two iterables pairwise using a function. If the iterables differ in length, extra elements are discarded.

When to use

Use when zipping two iterables in an array pipeline and each pair should become a computed array element instead of a tuple.

See

  • zip โ€” zip into tuples

Signature

declare const zipWith: {
<B, A, C>(that: readonly [B, B], f: (a: A, b: B) => C): (self: readonly [A, A]) => [C, ...Array<C>];
<B, A, C>(that: Iterable<B>, f: (a: A, b: B) => C): (self: Iterable<A>) => Array<C>;
<A, B, C>(self: readonly [A, A], that: readonly [B, B], f: (a: A, b: B) => C): [C, ...Array<C>];
<B, A, C>(self: Iterable<A>, that: Iterable<B>, f: (a: A, b: B) => C): Array<C>;
}

Example Zipping with addition

import { Array } from "effect"
Array.zipWith([1, 2, 3], [4, 5, 6], (a, b) => a + b) // => [5, 7, 9]