Implements 2D array using nested Arrays. Useful for implementing data grids, as it specifically provides row and column operations.
Cells are accessed by row, then column. Otherwise, it works very similarly to the Array class. The documentation examples usually omit converting Lists to Arrays for brevity.
Array2D's can be constructed from an Array or List of rows, where each row is an Array or List of cells.
Array2D.fromList
[ ["Row 1-Col 1", "Row 1-Col 2"]
, ["Row 2-Col 1", "Row 2-Col 2"]
]
If the nested arrays happen to be jagged, all rows will be truncated to the length of the smallest row! Be careful!
Array2D.fromList
[ [0, 1]
, [0, 1, 2]
]
-- Becomes:
[ [0, 1]
, [0, 1]
]
Most examples of nested models in Elm use Lists of elements with a unique, constant ID, e.g.:
type alias Cell = { uid : Int, ... }
This allows messages to always be routed to the correct element, even if elements are re-ordered, removed, added, etc. If you use the index of an element instead to create a long Task that will change the element when it ends, be aware that the target element's index may have changed during the task!
For data grids you are probably not going to be re-positioning cells. Most data grids simply modify cells in place, which is what Array2D is mainly intended for. The danger comes from inserting and deleting rows and columns. During such operations, you may want to temporarily make your grid "read-only" somehow.
{ data : Array (Array a)
, columns : Basics.Int
}
Base Array2D type
empty : Array2D a
Create an empty Array2D
fromArray : Array (Array a) -> Array2D a
Create an Array2D from an Array of Arrays. All rows will be truncated to the length of the shortest row.
let
row1 = Array.fromList [1, 2]
row2 = Array.fromList [2, 3]
in
fromArray (Array.fromList [row1, row2])
fromList : List (List a) -> Array2D a
Create an Array2D from a List of Lists.
fromList [[1, 2, 3], [4, 5, 6]]
initialize : Basics.Int -> Basics.Int -> (Basics.Int -> Basics.Int -> a) -> Array2D a
Initialize an Array2D. initialize rows cols f
creates an array
with the given dimensions with the element at index row col
initialized to the result of (f row col)
. Similar to
Array.initialize
.
initialize 2 3 (\row col -> row + col) == fromList [[0, 1, 2], [1, 2, 3]]
repeat : Basics.Int -> Basics.Int -> a -> Array2D a
Create a 2D of a given size, filled with a default element. Similar to Array.repeat
repeat 2 3 0 == [[0, 0, 0], [0, 0, 0]]
rows : Array2D a -> Basics.Int
Get the number of rows in an Array2D
rows [[1, 2, 3], [4, 5, 6]] == 2
columns : Array2D a -> Basics.Int
Get the number of columns in an Array2D
columns [[1, 2, 3], [4, 5, 6]] == 3
isEmpty : Array2D a -> Basics.Bool
Check if an Array2D is empty.
isEmpty [] == True
get : Basics.Int -> Basics.Int -> Array2D a -> Maybe a
Get a cell.
get 1 1 [[1, 2], [3, 4]] == Just 4
set : Basics.Int -> Basics.Int -> a -> Array2D a -> Array2D a
Update a cell, returning the changed Array2D.
set 0 0 -100 [[1, 2], [3, 4]] == [[-100, 2], [3, 4]]
getRow : Basics.Int -> Array2D a -> Maybe (Array a)
Get an individual row
getRow 1 [[1, 2], [3, 4]] == Just [3, 4]
appendRow : Array a -> a -> Array2D a -> Array2D a
Append a row. If the row is too long, it will be truncated, too short and it will be expanded with filler elements.
appendRow [3, 4] -1 [[1, 2]] == [[1, 2], [3, 4]]
-- Filler needed for short row:
appendRow [3] -1 [[1, 2]] == [[1, 2], [3, -1]]
deleteRow : Basics.Int -> Array2D a -> Array2D a
Delete a row. Does nothing if the index is out of bounds.
getColumn : Basics.Int -> Array2D a -> Maybe (Array a)
get column-th cell of each row as an Array
getColumn 1 [[1, 2], [3, 4]] == Just [2, 4]
appendColumn : Array a -> a -> Array2D a -> Array2D a
Append a column. Filler will be used if the column length is less than the number of rows in the Array2D. If it is longer, it will be truncated.
appendColumn [2, 2] -1 [[1], [1]] == [[1, 2], [1,2]]
-- Filler needed for short column:
appendColumn [2] -1 [[1], [1]] == [[1, 2], [1,-1]]
deleteColumn : Basics.Int -> Array2D a -> Array2D a
Delete a column. If the index is invalid, nothing will happen.
map : (a -> b) -> Array2D a -> Array2D b
2D version of Array.map.
map
(\cell -> toString cell)
[[1, 2], [3, 4]]
== [["1", "2"], ["3", "4"]]
indexedMap : (Basics.Int -> Basics.Int -> a -> b) -> Array2D a -> Array2D b
2D version of Array.indexedMap. First two arguments of map function are the row and column.
indexedMap
(\row column cell -> toString row)
[[1, 2], [3, 4]]
== [["0", "0"], ["1", "1"]]