Lists are a basic data type in Elixir for holding a collection of values. Lists are immutable, meaning they cannot be modified. Any operation that changes a list returns a new list. Lists implement the Enumerable protocol, which allows the use of Enum and Stream module functions.
Lists in Elixir are implemented as linked lists, and not as arrays of contiguous memory location. Therefore, accessing an element in a list takes linear time depending on the length of the list.
Lists can be written in literal form, head-tail notation, (which uses the cons
operator |
), or a combination of both:
# Literal Form
[]
[1]
[1, 2, 3]
# Head-tail Notation
[]
# same as [1]
[1 | []]
# same as [1, 2, 3]
[1 | [2 | [3 | []]]]
# Mixed
# same as [1, 2, 3]
[1 | [2, 3]]
There can also be more than one element before the cons (|
) operator.
# Multiple prepends
[1, 2, 3 | [4, 5]]
Head-tail notation can be used to append items to a list.
list = [2, 1]
[3, 2, 1] == [3 | list]
# => true
Appending elements to a list during iteration is considered an anti-pattern. Appending an element requires walking through the entire list and adding the element at the end, therefore, appending a new element in each iteration would require walking through the entire list in each iteration.
We can achieve the same result by prepending an element to the reversed list, and then reversing the result. Prepending is a fast operation and requires constant time.
# Appending to the end of a list (potentially slow)
[1, 2, 3] ++ [4] ++ [5] ++ [6]
# Prepend to the start of a list (faster, due to the nature of linked lists)
[6 | [5 | [4 | [3, 2, 1]]]]
# then reverse!
There are several common Kernel
functions for lists:
hd/1
returns the head of a list -- the first item in a list.tl/1
returns the tail of the list -- the list minus the first item.length/1
returns the number items in the list.in/2
returns a boolean value indicating whether the item is an element in the list.There is also the List
module.
Lists may contain any data type and a mix of different data types.
list = [1, :a, 2.0, "string"]