# Array

The `Array` module is a functional toolkit for working with JavaScript arrays. It operates on plain `ReadonlyArray<A>` values — the built-in array type — and adds constructors, transformations, searches, folds, grouping, sorting, and set-like operations around them.

Three properties hold across the whole module:

- **Nothing mutates.** Operations that transform, reorder, or update a collection allocate a new array; your input is left untouched.
- **Functions are dual.** Every combinator can be called data-first (`Array.map(xs, f)`) or data-last for pipelines (`pipe(xs, Array.map(f))`).
- **Non-emptiness is tracked in the type.** `NonEmptyReadonlyArray<A>` (and its mutable twin `NonEmptyArray<A>`) encode "at least one element" at the type level, so APIs like `headNonEmpty` can return `A` directly instead of `Option<A>`.

```ts
import { Array } from "effect"

// import the namespace — `Array` shadows the TS global on purpose,
// and Array.Array still exposes the native constructor if you need it.
```

## A worked pipeline

Most real code is a `pipe` of small steps. Here is a filter / map / group sequence in data-last style.

```ts
import { Array, pipe } from "effect"

const orders = [
  { id: 1, region: "us", total: 120 },
  { id: 2, region: "eu", total: 80 },
  { id: 3, region: "us", total: 50 },
  { id: 4, region: "eu", total: 200 }
]

const byRegion = pipe(
  orders,
  Array.filter((o) => o.total >= 60), // drop small orders
  Array.map((o) => ({ ...o, total: o.total * 1.1 })), // add 10% fee
  Array.groupBy((o) => o.region) // bucket by region
)

console.log(byRegion)
// {
//   us: [{ id: 1, region: "us", total: 132 }],
//   eu: [{ id: 2, region: "eu", total: 88 }, { id: 4, region: "eu", total: 220 }]
// }
```

## NonEmpty tracking

A `NonEmptyReadonlyArray<A>` is just `readonly [A, ...Array<A>]`. Because the first slot is guaranteed, total functions can skip `Option`:

```ts
import { Array } from "effect"

declare const xs: Array.NonEmptyReadonlyArray<number>

Array.headNonEmpty(xs) // : number   (not Option<number>)
Array.head([1, 2, 3]) //  : Option<number>  on a plain array
```

`isArrayNonEmpty` / `isReadonlyArrayNonEmpty` are refinements: passing the guard narrows the value so the `NonEmpty` APIs become available.

```ts
import { Array } from "effect"

const parse = (input: ReadonlyArray<number>) => {
  if (Array.isReadonlyArrayNonEmpty(input)) {
    // `input` is now NonEmptyReadonlyArray<number>
    return Array.headNonEmpty(input) // number, no Option
  }
  return 0
}
```

Operations that can *prove* the result is non-empty preserve the type: `map`, `sort`, `reverse`, `prepend`, `append`, `intersperse`, `rotate`, `copy`, `dedupe`, and the `*NonEmpty` variants all return `NonEmptyArray` when given non-empty input.

:::note
A `NonEmpty` return type describes what the function can *prove* statically. `filter` cannot prove its result is non-empty, so it always returns a plain `Array` even if every element happens to pass at runtime.
:::

---

# Reference

## Constructors

### make

Creates a `NonEmptyArray` from one or more literal elements; the element type is the union of all arguments.

```ts
import { Array } from "effect"

Array.make(1, 2, 3) // => [1, 2, 3]  (NonEmptyArray<number>)
```

### allocate

Creates an `Array` of the given length with uninitialized slots, typed as `A | undefined`. Fill it imperatively.

```ts
import { Array } from "effect"

Array.allocate<number>(3).length // => 3
```

### makeBy

Builds a `NonEmptyArray` of length `n` (normalized to >= 1) where element `i` is `f(i)`.

```ts
import { Array } from "effect"

Array.makeBy(5, (n) => n * 2) // => [0, 2, 4, 6, 8]
```

### range

Creates a `NonEmptyArray` of consecutive integers, inclusive on both ends. If `start > end`, returns `[start]`.

```ts
import { Array } from "effect"

Array.range(1, 3) // => [1, 2, 3]
Array.range(5, 2) // => [5]
```

### replicate

Creates a `NonEmptyArray` with a value repeated `n` times (`n` normalized to >= 1).

```ts
import { Array } from "effect"

Array.replicate("a", 3) // => ["a", "a", "a"]
```

### fromIterable

Converts any `Iterable` to an `Array`. If the input is already an array it is returned **by reference** (no copy) — use [`copy`](#copy) for a fresh array.

```ts
import { Array } from "effect"

Array.fromIterable(new Set([1, 2, 3])) // => [1, 2, 3]
```

### ensure

Normalizes a value that may be a single element or an array into an array. Handy for APIs that accept `A | Array<A>`.

```ts
import { Array } from "effect"

Array.ensure("a") // => ["a"]
Array.ensure(["a", "b"]) // => ["a", "b"]
```

### fromRecord

Converts a record into an array of `[key, value]` tuples, following `Object.entries` order.

```ts
import { Array } from "effect"

Array.fromRecord({ a: 1, b: 2 }) // => [["a", 1], ["b", 2]]
```

### fromOption

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

```ts
import { Array, Option } from "effect"

Array.fromOption(Option.some(1)) // => [1]
Array.fromOption(Option.none()) // => []
```

### empty

Creates a typed empty array.

```ts
import { Array } from "effect"

Array.empty<number>() // => []
```

### of

Wraps a single value in a `NonEmptyArray`.

```ts
import { Array } from "effect"

Array.of(1) // => [1]
```

### unfold

Builds an array by repeatedly applying a function to a seed. Return `Option.some([element, nextSeed])` to continue, `Option.none()` to stop.

```ts
import { Array, Option } from "effect"

Array.unfold(1, (n) => (n <= 5 ? Option.some([n, n + 1]) : Option.none()))
// => [1, 2, 3, 4, 5]
```

## Concatenation

### prepend

Adds a single element to the front, always returning a `NonEmptyArray`.

```ts
import { Array } from "effect"

Array.prepend([2, 3, 4], 1) // => [1, 2, 3, 4]
```

### prependAll

Prepends all elements of a prefix iterable. Non-empty if either input is non-empty.

```ts
import { Array } from "effect"

Array.prependAll([2, 3], [0, 1]) // => [0, 1, 2, 3]
```

### append

Adds a single element to the end, always returning a `NonEmptyArray`.

```ts
import { Array } from "effect"

Array.append([1, 2, 3], 4) // => [1, 2, 3, 4]
```

### appendAll

Concatenates two iterables. Non-empty if either input is non-empty.

```ts
import { Array } from "effect"

Array.appendAll([1, 2], [3, 4]) // => [1, 2, 3, 4]
```

## Predicates and guards

### isArray

Type guard for native arrays, narrowing to `Array<unknown>`. Delegates to `globalThis.Array.isArray`.

```ts
import { Array } from "effect"

Array.isArray([1, 2, 3]) // => true
Array.isArray(null) // => false
```

### isArrayEmpty

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

```ts
import { Array } from "effect"

Array.isArrayEmpty([]) // => true
Array.isArrayEmpty([1]) // => false
```

### isReadonlyArrayEmpty

Readonly counterpart of [`isArrayEmpty`](#isarrayempty), narrowing to `readonly []`.

```ts
import { Array } from "effect"

Array.isReadonlyArrayEmpty([] as ReadonlyArray<number>) // => true
```

### isArrayNonEmpty

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

```ts
import { Array } from "effect"

Array.isArrayNonEmpty([1, 2, 3]) // => true
Array.isArrayNonEmpty([]) // => false
```

### isReadonlyArrayNonEmpty

Readonly counterpart of [`isArrayNonEmpty`](#isarraynonempty), narrowing to `NonEmptyReadonlyArray`.

```ts
import { Array } from "effect"

Array.isReadonlyArrayNonEmpty([1] as ReadonlyArray<number>) // => true
```

## Accessing

### length

The number of elements, as a composable function.

```ts
import { Array } from "effect"

Array.length([1, 2, 3]) // => 3
```

### get

Reads an element at an index safely, returning `Option`. The index is floored; out-of-bounds returns `None`.

```ts
import { Array } from "effect"

Array.get([1, 2, 3], 1) // => Option.some(2)
Array.get([1, 2, 3], 10) // => Option.none()
```

### getUnsafe

Reads an element at an index, throwing `"Index out of bounds: <i>"` if invalid. Prefer [`get`](#get) for safe access.

```ts
import { Array } from "effect"

Array.getUnsafe([1, 2, 3], 1) // => 2
// Array.getUnsafe([1, 2, 3], 10) // throws Error
```

### head

The first element as an `Option`, or `None` for an empty array.

```ts
import { Array } from "effect"

Array.head([1, 2, 3]) // => Option.some(1)
Array.head([]) // => Option.none()
```

### headNonEmpty

The first element of a `NonEmptyReadonlyArray`, returned directly without `Option`.

```ts
import { Array } from "effect"

Array.headNonEmpty([1, 2, 3]) // => 1
```

### last

The last element as an `Option`, or `None` for an empty array.

```ts
import { Array } from "effect"

Array.last([1, 2, 3]) // => Option.some(3)
Array.last([]) // => Option.none()
```

### lastNonEmpty

The last element of a `NonEmptyReadonlyArray`, returned directly.

```ts
import { Array } from "effect"

Array.lastNonEmpty([1, 2, 3]) // => 3
```

### tail

All elements except the first, as an `Option` (allocates via `slice(1)`).

```ts
import { Array } from "effect"

Array.tail([1, 2, 3]) // => Option.some([2, 3])
Array.tail([]) // => Option.none()
```

### tailNonEmpty

All elements after the first of a `NonEmptyReadonlyArray`.

```ts
import { Array } from "effect"

Array.tailNonEmpty([1, 2, 3]) // => [2, 3]
```

### init

All elements except the last, as an `Option` (allocates via `slice(0, -1)`).

```ts
import { Array } from "effect"

Array.init([1, 2, 3]) // => Option.some([1, 2])
Array.init([]) // => Option.none()
```

### initNonEmpty

All elements before the last of a `NonEmptyReadonlyArray`.

```ts
import { Array } from "effect"

Array.initNonEmpty([1, 2, 3]) // => [1, 2]
```

### unprepend

Splits a `NonEmptyReadonlyArray` into `[head, tail]`.

```ts
import { Array } from "effect"

Array.unprepend([1, 2, 3, 4]) // => [1, [2, 3, 4]]
```

### unappend

Splits a `NonEmptyReadonlyArray` into `[init, last]`.

```ts
import { Array } from "effect"

Array.unappend([1, 2, 3, 4]) // => [[1, 2, 3], 4]
```

## Taking, dropping, slicing

### take

Keeps the first `n` elements (`n` clamped to `[0, length]`).

```ts
import { Array } from "effect"

Array.take([1, 2, 3, 4, 5], 3) // => [1, 2, 3]
```

### takeRight

Keeps the last `n` elements (`n` clamped to `[0, length]`).

```ts
import { Array } from "effect"

Array.takeRight([1, 2, 3, 4, 5], 3) // => [3, 4, 5]
```

### takeWhile

Keeps the leading prefix while the predicate holds, stopping at the first failure. Supports refinements. The predicate receives `(element, index)`.

```ts
import { Array } from "effect"

Array.takeWhile([1, 3, 2, 4, 1], (x) => x < 4) // => [1, 3, 2]
```

### takeWhileFilter

Keeps the leading prefix while a `Result`-returning filter succeeds, collecting the transformed success values. Stops at the first failure.

```ts
import { Array, Result } from "effect"

Array.takeWhileFilter([1, 2, 9, 3], (n) =>
  n < 5 ? Result.succeed(n * 10) : Result.failVoid
)
// => [10, 20]
```

### span

Splits into the longest matching prefix and the rest in a single pass — like `[takeWhile(p), dropWhile(p)]`. Supports refinements on the prefix.

```ts
import { Array } from "effect"

Array.span([1, 3, 2, 4, 5], (x) => x % 2 === 1) // => [[1, 3], [2, 4, 5]]
```

### drop

Removes the first `n` elements (`n` clamped to `[0, length]`).

```ts
import { Array } from "effect"

Array.drop([1, 2, 3, 4, 5], 2) // => [3, 4, 5]
```

### dropRight

Removes the last `n` elements (`n` clamped to `[0, length]`).

```ts
import { Array } from "effect"

Array.dropRight([1, 2, 3, 4, 5], 2) // => [1, 2, 3]
```

### dropWhile

Removes the leading prefix while the predicate holds, returning the rest.

```ts
import { Array } from "effect"

Array.dropWhile([1, 2, 3, 4, 5], (x) => x < 4) // => [4, 5]
```

### dropWhileFilter

Removes the leading prefix while a `Result`-returning filter succeeds, returning the remaining original elements.

```ts
import { Array, Result } from "effect"

Array.dropWhileFilter([1, 2, 9, 3], (n) =>
  n < 5 ? Result.succeed(n) : Result.failVoid
)
// => [9, 3]
```

### splitAt

Splits an iterable into a prefix and suffix at the given index (`n` floored, may be `0`).

```ts
import { Array } from "effect"

Array.splitAt([1, 2, 3, 4, 5], 3) // => [[1, 2, 3], [4, 5]]
```

### splitAtNonEmpty

Splits a `NonEmptyReadonlyArray` so the first part is guaranteed non-empty (`n` clamped to >= 1).

```ts
import { Array } from "effect"

Array.splitAtNonEmpty(["a", "b", "c", "d"], 2) // => [["a", "b"], ["c", "d"]]
```

### split

Splits an iterable into `n` roughly equal chunks; the last chunk may be shorter.

```ts
import { Array } from "effect"

Array.split([1, 2, 3, 4, 5, 6, 7, 8], 3) // => [[1, 2, 3], [4, 5, 6], [7, 8]]
```

### splitWhere

Splits at the first element matching the predicate; the matching element starts the second array.

```ts
import { Array } from "effect"

Array.splitWhere([1, 2, 3, 4, 5], (n) => n > 3) // => [[1, 2, 3], [4, 5]]
```

### chunksOf

Splits an iterable into non-overlapping chunks of length `n`; the last may be shorter. Each chunk is a `NonEmptyArray`. `chunksOf(n)([])` is `[]`.

```ts
import { Array } from "effect"

Array.chunksOf([1, 2, 3, 4, 5], 2) // => [[1, 2], [3, 4], [5]]
```

### window

Creates overlapping sliding windows of size `n`. Returns `[]` if `n <= 0` or the array is shorter than `n`.

```ts
import { Array } from "effect"

Array.window([1, 2, 3, 4, 5], 3) // => [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
Array.window([1, 2], 6) // => []
```

### copy

Creates a shallow copy, preserving `NonEmptyArray` in the type. Useful when you need a distinct reference (unlike [`fromIterable`](#fromiterable), which returns arrays by reference).

```ts
import { Array } from "effect"

const original = [1, 2, 3]
const copied = Array.copy(original)
original === copied // => false
```

### pad

Pads or truncates to exactly `n` elements: fills with `fill` if shorter, slices if longer. Returns `[]` when `n <= 0`.

```ts
import { Array } from "effect"

Array.pad([1, 2, 3], 6, 0) // => [1, 2, 3, 0, 0, 0]
Array.pad([1, 2, 3], 2, 0) // => [1, 2]
```

### chop

Repeatedly consumes prefixes via a function returning `[value, rest]`, until the remaining array is empty. The basis for custom splitting/grouping.

```ts
import { Array } from "effect"

Array.chop([1, 2, 3, 4], (as): [number, Array<number>] => [as[0] * 2, as.slice(1)])
// => [2, 4, 6, 8]
```

## Searching

### findFirstIndex

The index of the first element matching the predicate, as an `Option`.

```ts
import { Array } from "effect"

Array.findFirstIndex([5, 3, 8, 9], (x) => x > 5) // => Option.some(2)
```

### findLastIndex

The index of the last element matching the predicate, as an `Option`.

```ts
import { Array } from "effect"

Array.findLastIndex([1, 3, 8, 9], (x) => x < 5) // => Option.some(1)
```

### findFirst

The first element matching a predicate, refinement, or `Option`-returning function (find-and-transform), as an `Option`.

```ts
import { Array } from "effect"

Array.findFirst([1, 2, 3, 4, 5], (x) => x > 3) // => Option.some(4)
```

### findFirstWithIndex

Like [`findFirst`](#findfirst), but returns `Option.some([value, index])` for the first match.

```ts
import { Array } from "effect"

Array.findFirstWithIndex([1, 2, 3, 4, 5], (x) => x > 3) // => Option.some([4, 3])
```

### findLast

The last element matching a predicate, refinement, or `Option`-returning function, searching from the end.

```ts
import { Array } from "effect"

Array.findLast([1, 2, 3, 4, 5], (n) => n % 2 === 0) // => Option.some(4)
```

### contains

Checks membership using Effect's default equality (`Equal.asEquivalence()`).

```ts
import { Array } from "effect"

Array.contains(["a", "b", "c"], "c") // => true
```

### containsWith

Returns a membership-test function using a custom equivalence.

```ts
import { Array, pipe } from "effect"

const containsNum = Array.containsWith((a: number, b: number) => a === b)
pipe([1, 2, 3], containsNum(3)) // => true
```

## Modifying

All of these return new arrays; the input is never mutated.

### insertAt

Inserts an element at an index safely, returning `Option<NonEmptyArray>`. Valid indices are `0` to `length` (inserting at `length` appends).

```ts
import { Array } from "effect"

Array.insertAt(["a", "b", "c", "e"], 3, "d") // => Option.some(["a", "b", "c", "d", "e"])
```

### replace

Replaces the element at an index with a fixed value, returning `Option`. `None` if out of bounds.

```ts
import { Array } from "effect"

Array.replace([1, 2, 3], 1, 4) // => Option.some([1, 4, 3])
```

### modify

Applies a function to the element at an index, returning `Option`. `None` if out of bounds.

```ts
import { Array } from "effect"

Array.modify([1, 2, 3, 4], 2, (n) => n * 2) // => Option.some([1, 2, 6, 4])
Array.modify([1, 2, 3, 4], 5, (n) => n * 2) // => Option.none()
```

### remove

Removes the element at an index; returns a copy of the original if the index is out of bounds.

```ts
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]
```

### reverse

Reverses into a new array, preserving `NonEmptyArray`.

```ts
import { Array } from "effect"

Array.reverse([1, 2, 3, 4]) // => [4, 3, 2, 1]
```

### rotate

Rotates by `n` steps: positive rotates right, negative rotates left, wrapping around. `n` is rounded; preserves `NonEmptyArray`.

```ts
import { Array } from "effect"

Array.rotate(["a", "b", "c", "d"], 2) // => ["c", "d", "a", "b"]
```

### intersperse

Inserts a separator between every pair of elements, preserving `NonEmptyArray`. Empty input yields empty output.

```ts
import { Array } from "effect"

Array.intersperse([1, 2, 3], 0) // => [1, 0, 2, 0, 3]
```

### modifyHeadNonEmpty

Transforms the first element of a `NonEmptyReadonlyArray`.

```ts
import { Array } from "effect"

Array.modifyHeadNonEmpty([1, 2, 3], (n) => n * 10) // => [10, 2, 3]
```

### setHeadNonEmpty

Replaces the first element of a `NonEmptyReadonlyArray` with a fixed value.

```ts
import { Array } from "effect"

Array.setHeadNonEmpty([1, 2, 3], 10) // => [10, 2, 3]
```

### modifyLastNonEmpty

Transforms the last element of a `NonEmptyReadonlyArray`.

```ts
import { Array } from "effect"

Array.modifyLastNonEmpty([1, 2, 3], (n) => n * 2) // => [1, 2, 6]
```

### setLastNonEmpty

Replaces the last element of a `NonEmptyReadonlyArray` with a fixed value.

```ts
import { Array } from "effect"

Array.setLastNonEmpty([1, 2, 3], 4) // => [1, 2, 4]
```

## Sorting

### sort

Sorts by an `Order`, preserving `NonEmptyArray`.

```ts
import { Array, Order } from "effect"

Array.sort([3, 1, 4, 1, 5], Order.Number) // => [1, 1, 3, 4, 5]
```

### sortWith

Sorts by a derived key using a mapping function plus an `Order` for that key. Equivalent to `sort(Order.mapInput(order, f))`.

```ts
import { Array, Order } from "effect"

Array.sortWith(["aaa", "b", "cc"], (s) => s.length, Order.Number) // => ["b", "cc", "aaa"]
```

### sortBy

Sorts by multiple `Order`s in sequence: later orders break ties from earlier ones. Data-last only; preserves `NonEmptyArray`.

```ts
import { Array, Order, pipe } from "effect"

type User = { name: string; age: number }
const users: Array<User> = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 },
  { name: "Charlie", age: 30 }
]

pipe(
  users,
  Array.sortBy(
    Order.mapInput(Order.Number, (u: User) => u.age),
    Order.mapInput(Order.String, (u: User) => u.name)
  )
)
// => [{ name: "Bob", age: 25 }, { name: "Alice", age: 30 }, { name: "Charlie", age: 30 }]
```

### min

The minimum element of a `NonEmptyReadonlyArray` by an `Order`.

```ts
import { Array, Order } from "effect"

Array.min([3, 1, 2], Order.Number) // => 1
```

### max

The maximum element of a `NonEmptyReadonlyArray` by an `Order`.

```ts
import { Array, Order } from "effect"

Array.max([3, 1, 2], Order.Number) // => 3
```

### makeOrder

Creates an `Order` for arrays from an element `Order`. Arrays are compared element-wise; ties go to the shorter array.

```ts
import { Array, Order } from "effect"

const arrayOrder = Array.makeOrder(Order.Number)
arrayOrder([1, 2], [1, 3]) // => -1
```

### makeEquivalence

Creates an `Equivalence` for arrays from an element `Equivalence`. Equal when lengths match and all elements are pairwise equivalent.

```ts
import { Array } from "effect"

const eq = Array.makeEquivalence<number>((a, b) => a === b)
eq([1, 2, 3], [1, 2, 3]) // => true
```

## Zipping

### zip

Pairs elements by position; extra elements from the longer iterable are discarded. `NonEmptyArray` when both inputs are non-empty.

```ts
import { Array } from "effect"

Array.zip([1, 2, 3], ["a", "b"]) // => [[1, "a"], [2, "b"]]
```

### zipWith

Combines elements pairwise using a function; extra elements are discarded.

```ts
import { Array } from "effect"

Array.zipWith([1, 2, 3], [4, 5, 6], (a, b) => a + b) // => [5, 7, 9]
```

### unzip

Splits an array of pairs into two arrays — the inverse of [`zip`](#zip).

```ts
import { Array } from "effect"

Array.unzip([[1, "a"], [2, "b"], [3, "c"]]) // => [[1, 2, 3], ["a", "b", "c"]]
```

### cartesian

Every `[a, b]` pair from two arrays as tuples. Result length is `self.length * that.length`.

```ts
import { Array } from "effect"

Array.cartesian([1, 2], ["a", "b"]) // => [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]
```

### cartesianWith

Like [`cartesian`](#cartesian), but applies a combiner to each pair.

```ts
import { Array } from "effect"

Array.cartesianWith([1, 2], ["a", "b"], (a, b) => `${a}-${b}`)
// => ["1-a", "1-b", "2-a", "2-b"]
```

## Mapping and folding

### map

Transforms each element, preserving `NonEmptyArray`. The function receives `(element, index)`.

```ts
import { Array } from "effect"

Array.map([1, 2, 3], (x) => x * 2) // => [2, 4, 6]
```

### flatMap

Maps each element to an array and flattens the results. `NonEmptyArray` when both input and every mapped array are non-empty.

```ts
import { Array } from "effect"

Array.flatMap([1, 2, 3], (x) => [x, x * 2]) // => [1, 2, 2, 4, 3, 6]
```

### flatten

Flattens one level of nested arrays.

```ts
import { Array } from "effect"

Array.flatten([[1, 2], [], [3, 4], [5, 6]]) // => [1, 2, 3, 4, 5, 6]
```

### forEach

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

```ts
import { Array } from "effect"

Array.forEach([1, 2, 3], (n) => console.log(n)) // logs 1, 2, 3
```

### filterMap

Maps with a `Result`-returning filter, keeping only the success values. Failures are discarded.

```ts
import { Array, Result } from "effect"

Array.filterMap([1, 2, 3, 4], (n) =>
  n % 2 === 0 ? Result.succeed(n * 10) : Result.failVoid
)
// => [20, 40]
```

### filter

Keeps only elements satisfying a predicate or refinement. Always returns a plain `Array`.

```ts
import { Array } from "effect"

Array.filter([1, 2, 3, 4], (x) => x % 2 === 0) // => [2, 4]
```

### partition

Evaluates each element with a `Result`-returning filter and keeps both sides, as `[excluded, satisfying]`.

```ts
import { Array, Result } from "effect"

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

### separate

Splits an array of existing `Result`s into `[failures, successes]`. Equivalent to `partition(identity)`.

```ts
import { Array, Result } from "effect"

Array.separate([Result.succeed(1), Result.fail("error"), Result.succeed(2)])
// => [["error"], [1, 2]]
```

### reduce

Folds left-to-right into a single value. The function receives `(accumulator, element, index)`.

```ts
import { Array } from "effect"

Array.reduce([1, 2, 3], 0, (acc, n) => acc + n) // => 6
```

### reduceRight

Folds right-to-left into a single value.

```ts
import { Array } from "effect"

Array.reduceRight([1, 2, 3], 0, (acc, n) => acc + n) // => 6
```

### mapAccum

Maps while threading an accumulator through each step, returning `[finalState, mappedArray]`. The callback returns `[nextState, mappedValue]`.

```ts
import { Array } from "effect"

Array.mapAccum([1, 2, 3], 0, (acc, n) => [acc + n, acc + n]) // => [6, [1, 3, 6]]
```

### extend

Applies a function to each suffix of the array; at index `i` the function receives `self.slice(i)`.

```ts
import { Array } from "effect"

Array.extend([1, 2, 3], (as) => as.length) // => [3, 2, 1]
```

### scan

Folds left-to-right keeping every intermediate accumulator. Output length is `input.length + 1`, always a `NonEmptyArray` (starts with the initial value).

```ts
import { Array } from "effect"

Array.scan([1, 2, 3, 4], 0, (acc, n) => acc + n) // => [0, 1, 3, 6, 10]
```

### scanRight

Folds right-to-left keeping every intermediate accumulator. Output ends with the initial value.

```ts
import { Array } from "effect"

Array.scanRight([1, 2, 3, 4], 0, (acc, n) => acc + n) // => [10, 9, 7, 4, 0]
```

### every

Checks whether all elements satisfy the predicate; supports refinements for narrowing.

```ts
import { Array } from "effect"

Array.every([2, 4, 6], (x) => x % 2 === 0) // => true
Array.every([2, 3, 6], (x) => x % 2 === 0) // => false
```

### some

Checks whether at least one element satisfies the predicate, narrowing to `NonEmptyReadonlyArray` on success.

```ts
import { Array } from "effect"

Array.some([1, 3, 4], (x) => x % 2 === 0) // => true
Array.some([1, 3, 5], (x) => x % 2 === 0) // => false
```

### countBy

Counts how many elements satisfy a predicate. Returns `0` for an empty iterable.

```ts
import { Array } from "effect"

Array.countBy([1, 2, 3, 4, 5], (n) => n % 2 === 0) // => 2
```

### join

Joins string elements with a separator.

```ts
import { Array } from "effect"

Array.join(["a", "b", "c"], "-") // => "a-b-c"
```

## Grouping and dedupe

### group

Groups consecutive equal elements using Effect's default equality. Only **adjacent** equal values are grouped. Requires a `NonEmptyReadonlyArray`.

```ts
import { Array } from "effect"

Array.group([1, 1, 2, 2, 2, 3, 1]) // => [[1, 1], [2, 2, 2], [3], [1]]
```

### groupWith

Like [`group`](#group), but uses a custom equivalence.

```ts
import { Array } from "effect"

Array.groupWith(["a", "a", "b", "b", "c"], (x, y) => x === y)
// => [["a", "a"], ["b", "b"], ["c"]]
```

### groupBy

Groups all elements into a record by a key-returning function (key must be `string` or `symbol`). Elements need not be adjacent.

```ts
import { Array } from "effect"

const people = [
  { name: "Alice", team: "A" },
  { name: "Bob", team: "B" },
  { name: "Charlie", team: "A" }
]

Array.groupBy(people, (p) => p.team)
// => {
//   A: [{ name: "Alice", team: "A" }, { name: "Charlie", team: "A" }],
//   B: [{ name: "Bob", team: "B" }]
// }
```

### dedupe

Removes all duplicates using default equality, keeping the first occurrence. Preserves `NonEmptyArray`.

```ts
import { Array } from "effect"

Array.dedupe([1, 2, 1, 3, 2, 4]) // => [1, 2, 3, 4]
```

### dedupeWith

Like [`dedupe`](#dedupe), but uses a custom equivalence.

```ts
import { Array } from "effect"

Array.dedupeWith([1, 2, 2, 3, 3, 3], (a, b) => a === b) // => [1, 2, 3]
```

### dedupeAdjacent

Removes only consecutive duplicates using default equality; non-adjacent repeats are kept.

```ts
import { Array } from "effect"

Array.dedupeAdjacent([1, 1, 2, 2, 3, 1]) // => [1, 2, 3, 1]
```

### dedupeAdjacentWith

Like [`dedupeAdjacent`](#dedupeadjacent), but uses a custom equivalence.

```ts
import { Array } from "effect"

Array.dedupeAdjacentWith([1, 1, 2, 2, 3], (a, b) => a === b) // => [1, 2, 3]
```

## Set operations

These use Effect's `Equal` protocol by default; the `*With` variants take a custom equivalence.

### union

Elements present in either array, deduplicated using default equality.

```ts
import { Array } from "effect"

Array.union([1, 2], [2, 3]) // => [1, 2, 3]
```

### unionWith

Like [`union`](#union), but uses a custom equivalence.

```ts
import { Array } from "effect"

Array.unionWith([1, 2], [2, 3], (a, b) => a === b) // => [1, 2, 3]
```

### intersection

Elements present in both arrays (order from the first), using default equality.

```ts
import { Array } from "effect"

Array.intersection([1, 2, 3], [3, 4, 1]) // => [1, 3]
```

### intersectionWith

Like [`intersection`](#intersection), but uses a custom equivalence — useful for matching objects by a field.

```ts
import { Array, pipe } from "effect"

const a = [{ id: 1 }, { id: 2 }, { id: 3 }]
const b = [{ id: 3 }, { id: 4 }, { id: 1 }]
const eq = (x: { id: number }, y: { id: number }) => x.id === y.id

pipe(a, Array.intersectionWith(eq)(b)) // => [{ id: 1 }, { id: 3 }]
```

### difference

Elements in the first array that are not in the second, using default equality.

```ts
import { Array } from "effect"

Array.difference([1, 2, 3], [2, 3, 4]) // => [1]
```

### differenceWith

Like [`difference`](#difference), but uses a custom equivalence.

```ts
import { Array } from "effect"

Array.differenceWith<number>((a, b) => a === b)([1, 2, 3], [2, 3, 4]) // => [1]
```

## Option and Result interop

### getSomes

Extracts all `Some` values from an iterable of `Option`s, discarding `None`s.

```ts
import { Array, Option } from "effect"

Array.getSomes([Option.some(1), Option.none(), Option.some(2)]) // => [1, 2]
```

### getFailures

Extracts all failure values from an iterable of `Result`s, discarding successes.

```ts
import { Array, Result } from "effect"

Array.getFailures([Result.succeed(1), Result.fail("err"), Result.succeed(2)]) // => ["err"]
```

### getSuccesses

Extracts all success values from an iterable of `Result`s, discarding failures.

```ts
import { Array, Result } from "effect"

Array.getSuccesses([Result.succeed(1), Result.fail("err"), Result.succeed(2)]) // => [1, 2]
```

### liftPredicate

Lifts a predicate (or refinement) into an array-returning function: `[value]` if it holds, `[]` otherwise.

```ts
import { Array } from "effect"

const toEven = Array.liftPredicate((n: number) => n % 2 === 0)
toEven(2) // => [2]
toEven(1) // => []
```

### liftOption

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

```ts
import { Array, Option } from "effect"

const parse = Array.liftOption((s: string) => {
  const n = Number(s)
  return isNaN(n) ? Option.none() : Option.some(n)
})
parse("123") // => [123]
parse("abc") // => []
```

### liftResult

Lifts a `Result`-returning function: failures produce `[]`, successes produce `[value]`.

```ts
import { Array, Result } from "effect"

const parse = (s: string): Result.Result<number, Error> =>
  isNaN(Number(s)) ? Result.fail(new Error("NaN")) : Result.succeed(Number(s))

const lifted = Array.liftResult(parse)
lifted("42") // => [42]
lifted("x") // => []
```

### fromNullishOr

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

```ts
import { Array } from "effect"

Array.fromNullishOr(1) // => [1]
Array.fromNullishOr(null) // => []
```

### liftNullishOr

Lifts a nullable-returning function: `null`/`undefined` produces `[]`, anything else produces `[value]`.

```ts
import { Array } from "effect"

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

### flatMapNullishOr

Maps each element with a nullable-returning function, dropping `null`/`undefined` results.

```ts
import { Array } from "effect"

Array.flatMapNullishOr([1, 2, 3], (n) => (n % 2 === 0 ? null : n)) // => [1, 3]
```

## Pattern matching

### match

Branches on emptiness; `onNonEmpty` receives the full `NonEmptyReadonlyArray`.

```ts
import { Array } from "effect"

const describe = Array.match({
  onEmpty: () => "empty",
  onNonEmpty: (xs) => `${xs.length} items`
})
describe([]) // => "empty"
describe([1, 2, 3]) // => "3 items"
```

### matchLeft

Branches on emptiness, destructuring the non-empty case into `(head, tail)`.

```ts
import { Array } from "effect"

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

### matchRight

Branches on emptiness, destructuring the non-empty case into `(init, last)`.

```ts
import { Array } from "effect"

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

## Do-notation

The do-notation builds an array comprehension: each `bind` produces the cartesian product with all previous bindings (like nested loops), and `filter`/`map` add conditions and transformations.

### Do

The starting point — a single-element array of an empty scope.

```ts
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]]
```

### bind

Adds a named array variable to the scope, pairing each existing scope with every value the callback returns.

```ts
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" }]
```

### let

Adds a computed plain value to the scope (no new array dimension, so no cartesian product).

```ts
import { Array, pipe } from "effect"

pipe(
  Array.Do,
  Array.bind("x", () => [1, 2, 3]),
  Array.let("doubled", ({ x }) => x * 2)
)
// => [{ x: 1, doubled: 2 }, { x: 2, doubled: 4 }, { x: 3, doubled: 6 }]
```

### bindTo

Wraps each element of an existing array in an object with the given key, starting a scope. Equivalent to `Array.map(self, (a) => ({ [tag]: a }))`.

```ts
import { Array, pipe } from "effect"

pipe([1, 2, 3], Array.bindTo("x")) // => [{ x: 1 }, { x: 2 }, { x: 3 }]
```

## Reducers

These produce `Reducer` instances that combine arrays by concatenation, for use with APIs that accept a `Reducer`.

### getReadonlyReducerConcat

A `Reducer` that combines `ReadonlyArray` values by concatenation.

```ts
import { Array } from "effect"

const r = Array.getReadonlyReducerConcat<number>()
r.combine([1, 2], [3, 4]) // => [1, 2, 3, 4]
```

### makeReducerConcat

A `Reducer` that combines mutable `Array` values by concatenation.

```ts
import { Array } from "effect"

const r = Array.makeReducerConcat<number>()
r.combine([1, 2], [3, 4]) // => [1, 2, 3, 4]
```