This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

Array

A library for fast immutable arrays. The elements in an array must have the same type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast reads, updates, and appends.

Arrays

type Array a = Array

Representation of fast immutable arrays. You can create arrays of integers (Array Int) or strings (Array String) or any other type of value you can dream up.

Creating Arrays

empty : Array a

Return an empty array.

length empty == 0
repeat : Int -> a -> Array a

Creates an array with a given length, filled with a default element.

repeat 5 0     == fromList [0,0,0,0,0]
repeat 3 "cat" == fromList ["cat","cat","cat"]

Notice that repeat 3 x is the same as initialize 3 (always x).

initialize : Int -> (Int -> a) -> Array a

Initialize an array. initialize n f creates an array of length n with the element at index i initialized to the result of (f i).

initialize 4 identity    == fromList [0,1,2,3]
initialize 4 (\n -> n*n) == fromList [0,1,4,9]
initialize 4 (always 0)  == fromList [0,0,0,0]
fromList : List a -> Array a

Create an array from a list.

Basics

isEmpty : Array a -> Bool

Determine if an array is empty.

isEmpty empty == True
length : Array a -> Int

Return the length of an array.

length (fromList [1,2,3]) == 3
push : a -> Array a -> Array a

Push an element to the end of an array.

push 3 (fromList [1,2]) == fromList [1,2,3]
append : Array a -> Array a -> Array a

Append two arrays to a new one.

append (repeat 2 42) (repeat 3 81) == fromList [42,42,81,81,81]

Get and Set

get : Int -> Array a -> Maybe a

Return Just the element at the index or Nothing if the index is out of range.

get  0 (fromList [0,5,3]) == Just 0
get  2 (fromList [0,5,3]) == Just 3
get  5 (fromList [0,5,3]) == Nothing
get -1 (fromList [0,5,3]) == Nothing
set : Int -> a -> Array a -> Array a

Set the element at a particular index. Returns an updated array. If the index is out of range, the array is unaltered.

set 1 7 (fromList [1,2,3]) == fromList [1,7,3]

Taking Arrays Apart

slice : Int -> Int -> Array a -> Array a

Get a sub-section of an array: (slice start end array). The start is a zero-based index where we will start our slice. The end is a zero-based index that indicates the end of the slice. The slice extracts up to but not including end.

slice  0  3 (fromList [0,1,2,3,4]) == fromList [0,1,2]
slice  1  4 (fromList [0,1,2,3,4]) == fromList [1,2,3]

Both the start and end indexes can be negative, indicating an offset from the end of the array.

slice  1 -1 (fromList [0,1,2,3,4]) == fromList [1,2,3]
slice -2  5 (fromList [0,1,2,3,4]) == fromList [3,4]

This makes it pretty easy to pop the last element off of an array: slice 0 -1 array

toList : Array a -> List a

Create a list of elements from an array.

toList (fromList [3,5,8]) == [3,5,8]
toIndexedList : Array a -> List (Int, a)

Create an indexed list from an array. Each element of the array will be paired with its index.

toIndexedList (fromList ["cat","dog"]) == [(0,"cat"), (1,"dog")]

Mapping, Filtering, and Folding

map : (a -> b) -> Array a -> Array b

Apply a function on every element in an array.

map sqrt (fromList [1,4,9]) == fromList [1,2,3]
indexedMap : (Int -> a -> b) -> Array a -> Array b

Apply a function on every element with its index as first argument.

indexedMap (*) (fromList [5,5,5]) == fromList [0,5,10]
filter : (a -> Bool) -> Array a -> Array a

Keep only elements that satisfy the predicate:

filter isEven (fromList [1,2,3,4,5,6]) == (fromList [2,4,6])
foldl : (a -> b -> b) -> b -> Array a -> b

Reduce an array from the left. Read foldl as “fold from the left”.

foldl (::) [] (fromList [1,2,3]) == [3,2,1]
foldr : (a -> b -> b) -> b -> Array a -> b

Reduce an array from the right. Read foldr as “fold from the right”.

foldr (+) 0 (repeat 3 5) == 15
module Array exposing
  ( Array
  , empty, repeat, initialize, fromList
  , isEmpty, length, push, append
  , get, set
  , slice, toList, toIndexedList
  , map, indexedMap, filter, foldl, foldr
  )

{-| A library for fast immutable arrays. The elements in an array must have the
same type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast
reads, updates, and appends.

# Arrays
@docs Array

# Creating Arrays
@docs empty, repeat, initialize, fromList

# Basics
@docs isEmpty, length, push, append

# Get and Set
@docs get, set

# Taking Arrays Apart
@docs slice, toList, toIndexedList

# Mapping, Filtering, and Folding
@docs map, indexedMap, filter, foldl, foldr
-}

import Native.Array
import Basics exposing (..)
import Maybe exposing (..)
import List


{-| Representation of fast immutable arrays. You can create arrays of integers
(`Array Int`) or strings (`Array String`) or any other type of value you can
dream up.
-}
type Array a = Array


{-| Initialize an array. `initialize n f` creates an array of length `n` with
the element at index `i` initialized to the result of `(f i)`.

    initialize 4 identity    == fromList [0,1,2,3]
    initialize 4 (\n -> n*n) == fromList [0,1,4,9]
    initialize 4 (always 0)  == fromList [0,0,0,0]
-}
initialize : Int -> (Int -> a) -> Array a
initialize =
  Native.Array.initialize


{-| Creates an array with a given length, filled with a default element.

    repeat 5 0     == fromList [0,0,0,0,0]
    repeat 3 "cat" == fromList ["cat","cat","cat"]

Notice that `repeat 3 x` is the same as `initialize 3 (always x)`.
-}
repeat : Int -> a -> Array a
repeat n e =
  initialize n (always e)


{-| Create an array from a list.
-}
fromList : List a -> Array a
fromList =
  Native.Array.fromList


{-| Create a list of elements from an array.

    toList (fromList [3,5,8]) == [3,5,8]
-}
toList : Array a -> List a
toList =
  Native.Array.toList


-- TODO: make this a native function.
{-| Create an indexed list from an array. Each element of the array will be
paired with its index.

    toIndexedList (fromList ["cat","dog"]) == [(0,"cat"), (1,"dog")]
-}
toIndexedList : Array a -> List (Int, a)
toIndexedList array =
  List.map2
    (,)
    (List.range 0 (Native.Array.length array - 1))
    (Native.Array.toList array)


{-| Apply a function on every element in an array.

    map sqrt (fromList [1,4,9]) == fromList [1,2,3]
-}
map : (a -> b) -> Array a -> Array b
map =
  Native.Array.map


{-| Apply a function on every element with its index as first argument.

    indexedMap (*) (fromList [5,5,5]) == fromList [0,5,10]
-}
indexedMap : (Int -> a -> b) -> Array a -> Array b
indexedMap =
  Native.Array.indexedMap


{-| Reduce an array from the left. Read `foldl` as “fold from the left”.

    foldl (::) [] (fromList [1,2,3]) == [3,2,1]
-}
foldl : (a -> b -> b) -> b -> Array a -> b
foldl =
  Native.Array.foldl


{-| Reduce an array from the right. Read `foldr` as “fold from the right”.

    foldr (+) 0 (repeat 3 5) == 15
-}
foldr : (a -> b -> b) -> b -> Array a -> b
foldr =
  Native.Array.foldr


{-| Keep only elements that satisfy the predicate:

    filter isEven (fromList [1,2,3,4,5,6]) == (fromList [2,4,6])
-}
filter : (a -> Bool) -> Array a -> Array a
filter isOkay arr =
  let
    update x xs =
      if isOkay x then
        Native.Array.push x xs
      else
        xs
  in
    Native.Array.foldl update Native.Array.empty arr

{-| Return an empty array.

    length empty == 0
-}
empty : Array a
empty =
  Native.Array.empty


{-| Push an element to the end of an array.

    push 3 (fromList [1,2]) == fromList [1,2,3]
-}
push : a -> Array a -> Array a
push =
  Native.Array.push


{-| Return Just the element at the index or Nothing if the index is out of range.

    get  0 (fromList [0,5,3]) == Just 0
    get  2 (fromList [0,5,3]) == Just 3
    get  5 (fromList [0,5,3]) == Nothing
    get -1 (fromList [0,5,3]) == Nothing

-}
get : Int -> Array a -> Maybe a
get i array =
  if 0 <= i && i < Native.Array.length array then
    Just (Native.Array.get i array)
  else
    Nothing


{-| Set the element at a particular index. Returns an updated array.
If the index is out of range, the array is unaltered.

    set 1 7 (fromList [1,2,3]) == fromList [1,7,3]
-}
set : Int -> a -> Array a -> Array a
set =
  Native.Array.set


{-| Get a sub-section of an array: `(slice start end array)`. The `start` is a
zero-based index where we will start our slice. The `end` is a zero-based index
that indicates the end of the slice. The slice extracts up to but not including
`end`.

    slice  0  3 (fromList [0,1,2,3,4]) == fromList [0,1,2]
    slice  1  4 (fromList [0,1,2,3,4]) == fromList [1,2,3]

Both the `start` and `end` indexes can be negative, indicating an offset from
the end of the array.

    slice  1 -1 (fromList [0,1,2,3,4]) == fromList [1,2,3]
    slice -2  5 (fromList [0,1,2,3,4]) == fromList [3,4]

This makes it pretty easy to `pop` the last element off of an array: `slice 0 -1 array`
-}
slice : Int -> Int -> Array a -> Array a
slice =
  Native.Array.slice


{-| Return the length of an array.

    length (fromList [1,2,3]) == 3
-}
length : Array a -> Int
length =
  Native.Array.length


{-| Determine if an array is empty.

    isEmpty empty == True
-}
isEmpty : Array a -> Bool
isEmpty array =
    length array == 0


{-| Append two arrays to a new one.

    append (repeat 2 42) (repeat 3 81) == fromList [42,42,81,81,81]
-}
append : Array a -> Array a -> Array a
append =
  Native.Array.append