Lists
Mix.install([
{:kino, github: "livebook-dev/kino", override: true},
{:kino_lab, "~> 0.1.0-dev", github: "jonatanklosko/kino_lab"},
{:vega_lite, "~> 0.1.4"},
{:kino_vega_lite, "~> 0.1.1"},
{:benchee, "~> 0.1"},
{:ecto, "~> 3.7"},
{:math, "~> 0.7.0"},
{:faker, "~> 0.17.0"},
{:utils, path: "#{__DIR__}/../utils"}
])
Navigation
Lists
Lists store a list of other data types. Data types within a list are called elements.
flowchart
subgraph List
a[Element] --> b[Element] --> c[Element] --> d[Element]
end
Use square brackets []
to
create a list, and then separate each value with a comma ,
.
[1, 2, 3]
Lists can contain any data type in any combination, even other lists.
["a", 2, "c", []]
Lists are used to represent a collection of information. For example, a shopping list, a to-do list, or a list of tags on an article.
Indexes
An index is the position of an element in a list.
In programming, we count indexes starting at 0. Why? The short answer is, it relates to how computer hardware works.
So take this example list.
["a", "b", "c"]
-
"a"
is at index0
-
"b"
is at index1
-
"c"
is at index2
flowchart
subgraph Index
0 --> 1 --> 2
end
subgraph Elements
a --> b --> c
end
Your Turn
In the Elixir cell below, Create a list of your favourite foods as strings.
List Operators
List operators are useful for manipulating lists.
++
allows you to add lists together.
[1] ++ [2]
--
allows you to subtract matching elements from a list.
[1, 2, 3] -- [2, 3]
Unlike Arithmetic Operators
, Lists do not follow the BEDMAS order of operations.
For example, what do you think the result of [1, 2] -- [1] -- [2]
should be?
Intuitively, you might think it would be an empty list []
. Because
[1, 2] -- [1] -- [2]
Becomes [2]
when you subtract [1]
[2] -- [2]
And then becomes []
when you subtract [2]
[1, 2] -- [1] -- [2]
However, this is not the case. It’s actually [2]
. Why? because list operations evaluate from
right to left.
[1, 2] -- [1] -- [2]
To avoid writing unintuitive code, you can either use brackets or split values in to variables to break up the operations into steps using the match operator.
([1, 2] -- [1]) -- [2]
step1 = [1, 2]
step2 = step1 -- [1]
step2 -- [2]
Your Turn
In the Elixir cell below, add [1, 2, 3]
and [4, 5, 6]
together to make [1, 2, 3, 4, 5, 6].
In the Elixir cell below, remove [1]
from [1, 1, 2, 3]
to make [1, 2, 3]
Prepending
We can prepend elements to a list using [element | list]
syntax.
For example, we can prepend 1
to the list [2, 3]
to make [1, 2, 3]
flowchart
1 --> l[2, 3]
[1 | [2, 3]]
You can use a variable in place of a hard-coded list.
list = [2, 3]
[1 | list]
Your Turn
In the Elixir cell below, prepend ["hello"]
to the list ["world"]
to make ["hello", "world"]
Pattern Matching Lists
Sometimes a collection is large, and it’s unreasonable to pattern match on every element.
Maps don’t have this problem so much, because you don’t need to include every key in the match
%{key1: value} = %{key1: "value1", key2: "value2"}
value
This poses an issue for lists though who seem to require a match for every element.
[one] = [1, 2]
To get around this, you can use the [head | tail]
syntax for prepending elements to a list.
The head is the first element of the list.
[head | _tail] = [1, 2, 3, 4, 5, 6, 7]
head
The tail is rest of the elements in the list.
[_head | tail] = [1, 2, 3, 4, 5, 6, 7]
tail
You can access multiple elements at the start of the list separated by commas ,
.
[one, two | _tail] = [1, 2, 3, 4, 5, 6, 7]
{one, two}
Why head and tail? That’s because under the hood lists in Elixir are a linked list. Essentially each element in the list knows the location of the next element in memory.
The head is the current element in the list, and the tail is the link to the remaining elements.
flowchart LR
subgraph Head
L
end
subgraph Tail
I
S
T
end
L -- tail --> I --> S --> T
Your Turn
Pattern match on only the first element in this list using [head | tail]
syntax.
Replace list
with your answer.
list = [1, 2, 3]
Commit Your Progress
Run the following in your command line from the project folder to track and save your progress in a Git commit.
$ git add .
$ git commit -m "finish lists section"