# Data.Array

- Package
- purescript-arrays
- Repository
- purescript/purescript-arrays

Helper functions for working with immutable Javascript arrays.

*Note*: Depending on your use-case, you may prefer to use `Data.List`

or
`Data.Sequence`

instead, which might give better performance for certain
use cases. This module is useful when integrating with JavaScript libraries
which use arrays, but immutable arrays are not a practical data structure
for many use cases due to their poor asymptotics.

In addition to the functions in this module, Arrays have a number of useful instances:

`Functor`

, which provides`map :: forall a b. (a -> b) -> Array a -> Array b`

`Apply`

, which provides`(<*>) :: forall a b. Array (a -> b) -> Array a -> Array b`

. This function works a bit like a Cartesian product; the result array is constructed by applying each function in the first array to each value in the second, so that the result array ends up with a length equal to the product of the two arguments' lengths.`Bind`

, which provides`(>>=) :: forall a b. (a -> Array b) -> Array a -> Array b`

(this is the same as`concatMap`

).`Semigroup`

, which provides`(<>) :: forall a. Array a -> Array a -> Array a`

, for concatenating arrays.`Foldable`

, which provides a slew of functions for*folding*(also known as*reducing*) arrays down to one value. For example,`Data.Foldable.or`

tests whether an array of`Boolean`

values contains at least one`true`

value.`Traversable`

, which provides the PureScript version of a for-loop, allowing you to STAI.iterate over an array and accumulate effects.

### #fromFoldable Source

`fromFoldable :: forall f. Foldable f => f ~> Array`

Convert a `Foldable`

structure into an `Array`

.

```
fromFoldable (Just 1) = [1]
fromFoldable (Nothing) = []
```

### #toUnfoldable Source

`toUnfoldable :: forall f. Unfoldable f => Array ~> f`

Convert an `Array`

into an `Unfoldable`

structure.

### #(..) Source

Operator alias for Data.Array.range *(non-associative / precedence 8)*

An infix synonym for `range`

.

```
2 .. 5 = [2, 3, 4, 5]
```

### #some Source

`some :: forall f a. Alternative f => Lazy (f (Array a)) => f a -> f (Array a)`

Attempt a computation multiple times, requiring at least one success.

The `Lazy`

constraint is used to generate the result lazily, to ensure
termination.

### #many Source

`many :: forall f a. Alternative f => Lazy (f (Array a)) => f a -> f (Array a)`

Attempt a computation multiple times, returning as many successful results as possible (possibly zero).

The `Lazy`

constraint is used to generate the result lazily, to ensure
termination.

### #(:) Source

Operator alias for Data.Array.cons *(right-associative / precedence 6)*

An infix alias for `cons`

.

```
1 : [2, 3, 4] = [1, 2, 3, 4]
```

Note, the running time of this function is `O(n)`

.

### #uncons Source

`uncons :: forall a. Array a -> Maybe { head :: a, tail :: Array a }`

Break an array into its first element and remaining elements.

Using `uncons`

provides a way of writing code that would use cons patterns
in Haskell or pre-PureScript 0.7:

```
f (x : xs) = something
f [] = somethingElse
```

Becomes:

```
f arr = case uncons arr of
Just { head: x, tail: xs } -> something
Nothing -> somethingElse
```

### #(!!) Source

Operator alias for Data.Array.index *(left-associative / precedence 8)*

An infix version of `index`

.

```
sentence = ["Hello", "World", "!"]
sentence !! 0 = Just "Hello"
sentence !! 7 = Nothing
```

### #elemLastIndex Source

`elemLastIndex :: forall a. Eq a => a -> Array a -> Maybe Int`

Find the index of the last element equal to the specified element.

```
elemLastIndex "a" ["a", "b", "a", "c"] = Just 2
elemLastIndex "Earth" ["Hello", "World", "!"] = Nothing
```

### #findLastIndex Source

`findLastIndex :: forall a. (a -> Boolean) -> Array a -> Maybe Int`

Find the last index for which a predicate holds.

```
findLastIndex (contains $ Pattern "b") ["a", "bb", "b", "d"] = Just 2
findLastIndex (contains $ Pattern "x") ["a", "bb", "b", "d"] = Nothing
```

### #updateAtIndices Source

`updateAtIndices :: forall t a. Foldable t => t (Tuple Int a) -> Array a -> Array a`

Change the elements at the specified indices in index/value pairs. Out-of-bounds indices will have no effect.

```
updates = [Tuple 0 "Hi", Tuple 2 "." , Tuple 10 "foobar"]
updateAtIndices updates ["Hello", "World", "!"] = ["Hi", "World", "."]
```

### #modifyAt Source

`modifyAt :: forall a. Int -> (a -> a) -> Array a -> Maybe (Array a)`

Apply a function to the element at the specified index, creating a new
array, or returning `Nothing`

if the index is out of bounds.

```
modifyAt 1 toUpper ["Hello", "World"] = Just ["Hello", "WORLD"]
modifyAt 10 toUpper ["Hello", "World"] = Nothing
```

### #modifyAtIndices Source

`modifyAtIndices :: forall t a. Foldable t => t Int -> (a -> a) -> Array a -> Array a`

Apply a function to the element at the specified indices, creating a new array. Out-of-bounds indices will have no effect.

```
indices = [1, 3]
modifyAtIndices indices toUpper ["Hello", "World", "and", "others"]
= ["Hello", "WORLD", "and", "OTHERS"]
```

### #alterAt Source

`alterAt :: forall a. Int -> (a -> Maybe a) -> Array a -> Maybe (Array a)`

Update or delete the element at the specified index by applying a
function to the current value, returning a new array or `Nothing`

if the
index is out-of-bounds.

```
alterAt 1 (stripSuffix $ Pattern "!") ["Hello", "World!"]
= Just ["Hello", "World"]
alterAt 1 (stripSuffix $ Pattern "!!!!!") ["Hello", "World!"]
= Just ["Hello"]
alterAt 10 (stripSuffix $ Pattern "!") ["Hello", "World!"] = Nothing
```

### #partition Source

`partition :: forall a. (a -> Boolean) -> Array a -> { yes :: Array a, no :: Array a }`

Partition an array using a predicate function, creating a set of new arrays. One for the values satisfying the predicate function and one for values that don't.

```
partition (_ > 0) [-1, 4, -5, 7] = { yes: [4, 7], no: [-1, -5] }
```

### #filterA Source

`filterA :: forall a f. Applicative f => (a -> f Boolean) -> Array a -> f (Array a)`

Filter where the predicate returns a `Boolean`

in some `Applicative`

.

```
powerSet :: forall a. Array a -> Array (Array a)
powerSet = filterA (const [true, false])
```

### #mapMaybe Source

`mapMaybe :: forall a b. (a -> Maybe b) -> Array a -> Array b`

Apply a function to each element in an array, keeping only the results which contain a value, creating a new array.

```
parseEmail :: String -> Maybe Email
parseEmail = ...
mapMaybe parseEmail ["a.com", "hello@example.com", "--"]
= [Email {user: "hello", domain: "example.com"}]
```

### #mapWithIndex Source

`mapWithIndex :: forall a b. (Int -> a -> b) -> Array a -> Array b`

Apply a function to each element in an array, supplying a generated zero-based index integer along with the element, creating an array with the new elements.

```
prefixIndex index element = show index <> element
mapWithIndex prefixIndex ["Hello", "World"] = ["0Hello", "1World"]
```

### #sortBy Source

`sortBy :: forall a. (a -> a -> Ordering) -> Array a -> Array a`

Sort the elements of an array in increasing order, where elements are compared using the specified partial ordering, creating a new array.

```
compareLength a b = compare (length a) (length b)
sortBy compareLength [[1, 2, 3], [7, 9], [-2]] = [[-2],[7,9],[1,2,3]]
```

### #span Source

`span :: forall a. (a -> Boolean) -> Array a -> { init :: Array a, rest :: Array a }`

Split an array into two parts:

- the longest initial subarray for which all elements satisfy the specified predicate
- the remaining elements

```
span (\n -> n % 2 == 1) [1,3,2,4,5] == { init: [1,3], rest: [2,4,5] }
```

Running time: `O(n)`

.

### #group Source

`group :: forall a. Eq a => Array a -> Array (NonEmptyArray a)`

Group equal, consecutive elements of an array into arrays.

```
group [1,1,2,2,1] == [NonEmpty 1 [1], NonEmpty 2 [2], NonEmpty 1 []]
```

### #group' Source

`group' :: forall a. Ord a => Array a -> Array (NonEmptyArray a)`

Sort and then group the elements of an array into arrays.

```
group' [1,1,2,2,1] == [NonEmpty 1 [1,1],NonEmpty 2 [2]]
```

### #groupBy Source

`groupBy :: forall a. (a -> a -> Boolean) -> Array a -> Array (NonEmptyArray a)`

Group equal, consecutive elements of an array into arrays, using the specified equivalence relation to detemine equality.

```
groupBy (\a b -> odd a && odd b) [1, 3, 2, 4, 3, 3]
= [NonEmpty 1 [3], NonEmpty 2 [] , NonEmpty 4 [], NonEmpty 3 [3]]
```

### #nubByEq Source

`nubByEq :: forall a. (a -> a -> Boolean) -> Array a -> Array a`

Remove the duplicates from an array, where element equality is determined by the specified equivalence relation, creating a new array.

This less efficient version of `nubBy`

only requires an equivalence
relation.

```
mod3eq a b = a `mod` 3 == b `mod` 3
nubByEq mod3eq [1, 3, 4, 5, 6] = [1, 3, 5]
```

### #unionBy Source

`unionBy :: forall a. (a -> a -> Boolean) -> Array a -> Array a -> Array a`

Calculate the union of two arrays, using the specified function to determine equality of elements. Note that duplicates in the first array are preserved while duplicates in the second array are removed.

```
mod3eq a b = a `mod` 3 == b `mod` 3
unionBy mod3eq [1, 5, 1, 2] [3, 4, 3, 3] = [1, 5, 1, 2, 3]
```

### #deleteBy Source

`deleteBy :: forall a. (a -> a -> Boolean) -> a -> Array a -> Array a`

Delete the first element of an array which matches the specified value, under the equivalence relation provided in the first argument, creating a new array.

```
mod3eq a b = a `mod` 3 == b `mod` 3
deleteBy mod3eq 6 [1, 3, 4, 3] = [1, 4, 3]
```

### #difference Source

`difference :: forall a. Eq a => Array a -> Array a -> Array a`

Delete the first occurrence of each element in the second array from the first array, creating a new array.

```
difference [2, 1] [2, 3] = [1]
```

Running time: `O(n*m)`

, where n is the length of the first array, and m is
the length of the second.

### #intersectBy Source

`intersectBy :: forall a. (a -> a -> Boolean) -> Array a -> Array a -> Array a`

Calculate the intersection of two arrays, using the specified equivalence relation to compare elements, creating a new array. Note that duplicates in the first array are preserved while duplicates in the second array are removed.

```
mod3eq a b = a `mod` 3 == b `mod` 3
intersectBy mod3eq [1, 2, 3] [4, 6, 7] = [1, 3]
```

### #zipWith Source

`zipWith :: forall a b c. (a -> b -> c) -> Array a -> Array b -> Array c`

Apply a function to pairs of elements at the same index in two arrays, collecting the results in a new array.

If one array is longer, elements will be discarded from the longer array.

For example

```
zipWith (*) [1, 2, 3] [4, 5, 6, 7] == [4, 10, 18]
```

### #zipWithA Source

`zipWithA :: forall m a b c. Applicative m => (a -> b -> m c) -> Array a -> Array b -> m (Array c)`

A generalization of `zipWith`

which accumulates results in some
`Applicative`

functor.

```
sndChars = zipWithA (\a b -> charAt 2 (a <> b))
sndChars ["a", "b"] ["A", "B"] = Nothing -- since "aA" has no 3rd char
sndChars ["aa", "b"] ["AA", "BBB"] = Just ['A', 'B']
```

### #unsafeIndex Source

`unsafeIndex :: forall a. Partial => Array a -> Int -> a`

Find the element of an array at the specified index.

```
unsafePartial $ unsafeIndex ["a", "b", "c"] 1 = "b"
```

Using `unsafeIndex`

with an out-of-range index will not immediately raise a runtime error.
Instead, the result will be undefined. Most attempts to subsequently use the result will
cause a runtime error, of course, but this is not guaranteed, and is dependent on the backend;
some programs will continue to run as if nothing is wrong. For example, in the JavaScript backend,
the expression `unsafePartial (unsafeIndex [true] 1)`

has type `Boolean`

;
since this expression evaluates to `undefined`

, attempting to use it in an `if`

statement will cause
the else branch to be taken.

## Re-exports from **Data.**Foldable

### #intercalate Source

`intercalate :: forall f m. Foldable f => Monoid m => m -> f m -> m`

Fold a data structure, accumulating values in some `Monoid`

,
combining adjacent elements using the specified separator.

For example:

```
> intercalate ", " ["Lorem", "ipsum", "dolor"]
= "Lorem, ipsum, dolor"
> intercalate "*" ["a", "b", "c"]
= "a*b*c"
> intercalate [1] [[2, 3], [4, 5], [6, 7]]
= [2, 3, 1, 4, 5, 1, 6, 7]
```

### #any Source

`any :: forall a b f. Foldable f => HeytingAlgebra b => (a -> b) -> f a -> b`

`any f`

is the same as `or <<< map f`

; map a function over the structure,
and then get the disjunction of the results.

### #all Source

`all :: forall a b f. Foldable f => HeytingAlgebra b => (a -> b) -> f a -> b`

`all f`

is the same as `and <<< map f`

; map a function over the structure,
and then get the conjunction of the results.

## Re-exports from **Data.**Traversable

### #scanr Source

`scanr :: forall a b f. Traversable f => (a -> b -> b) -> b -> f a -> f b`

Fold a data structure from the right, keeping all intermediate results
instead of only the final result. Note that the initial value does not
appear in the result (unlike Haskell's `Prelude.scanr`

).

```
scanr (+) 0 [1,2,3] = [6,5,3]
scanr (flip (-)) 10 [1,2,3] = [4,5,7]
```

### #scanl Source

`scanl :: forall a b f. Traversable f => (b -> a -> b) -> b -> f a -> f b`

Fold a data structure from the left, keeping all intermediate results
instead of only the final result. Note that the initial value does not
appear in the result (unlike Haskell's `Prelude.scanl`

).

```
scanl (+) 0 [1,2,3] = [1,3,6]
scanl (-) 10 [1,2,3] = [9,7,4]
```