Lists and tuples in Elixir

We will keep learning two of the most used collection data types in Elixir: lists and tuples. They are immutable!

Like lists, tuples can hold any value. In Elixir data structure they are immutable, so every operation will return a new List or a new To…


This content originally appeared on DEV Community and was authored by Rhaenyra

We will keep learning two of the most used collection data types in Elixir: lists and tuples. They are immutable!

Like lists, tuples can hold any value. In Elixir data structure they are immutable, so every operation will return a new List or a new Touple.

(Link)List

Elixir uses square brackets to specify a list of values. List operators never modify the existing list. You can freely pass the data around with the guarantee that no one will mutate it in memory—only transform it.

Linked lists hold zero, one, or more elements in the chosen order.

iex> [1, 2, true, 3]
[1, 2, true, 3]

iex> [1, "two", 3, :four]
[1, "two", 3, :four]

iex> [1, 3, "two", :four]
[1, 3, "two", :four]

iex> length([1, 2, 3])
3

List concatenated

Two lists can be concatenated or subtracted using the ++/2 and --/2 operators.

  • left ++ right

    Concatenates a proper list and a term, returning a list. If the right operand is not a proper list, it returns an improper list. If the left operand is not a proper list, it raises an ArgumentError.

  • left -- right

    List subtraction operator. Removes the first occurrence of each element in the left list for each element in the right list.

iex>[1] ++ [2,3]
[1, 2, 3]
iex> [1, 2, 3] ++ [4, 6, 6]
[1, 2, 3, 4, 5, 6]
iex>[1, 2] ++ 3 
[1, 2 | 3] 
iex> [1, 2] ++ {3, 4} 
[1, 2 | {3, 4}] 

iex> [1, 2, 3] -- [1, 2]
[3]
iex> [1, 2, 3, 2, 1] -- [1, 2, 2]
[3, 1]
iex> [1, 2, 3] -- [2] -- [3]
[1, 3]
iex> [1, 2, 3] -- ([2] -- [3])
[1, 3]
iex> [1, true, 2, false, 3, true] -- [true, false]
[1, 2, 3, true]

List prepended

An element can be prepended to a list using |. Due to their cons cell-based representation, prepending an element to a list is always fast (constant time), while appending becomes slower as the list grows in size (linear time):

iex(1)> new = 0
iex(2)> list = [1, 2, 3]
iex(3)> [new | list]
[0, 1, 2, 3]

iex(1)>list = [1, 2, 3]
iex(2)[0 | list] # fast
[0, 1, 2, 3]
iex(3)list ++ [4] # slow
[1, 2, 3, 4]

Head and tail of list

Lists in Elixir are effectively linked lists, which means they are internally represented in pairs containing the head and the tail of a list.

iex> [head | tail] = [1, 2, 3]
iex> head
1
iex> tail
[2, 3]

The head is the first element of a list and the tail is the remainder of the list. They can be retrieved with the functions hd/1 and tl/1

  • hd(list)

    Returns the head of a list. Raises ArgumentError if the list is empty.

  • tl(list)

    Returns the tail of a list, which is the list without its first element. Raises ArgumentError if the list is empty.

iex> hd([1, 2, 3, 4])
1
iex> hd([1 | 2])
1
iex> hd([])
** (ArgumentError) argument error

iex> tl([1, 2, 3, :go])
[2, 3, :go]
iex>tl([:a, :b | :improper_end])
[:b | :improper_end]
iex>tl([:a | %{b: 1}])
%{b: 1}
iex>tl([:one])
[]
iex>tl([])
** (ArgumentError) argument error

Tuples

Elixir uses curly brackets to define tuples. Tuples store elements contiguously in memory, which means accessing a tuple element by index or getting the tuple size is a fast operation. Indexes start from zero.

iex> {}
{}
iex> {:ok, "hello"}
{:ok, "hello"}
iex> {1, :two, "three"}
{1, :two, "three"}
iex> tuple_size({:ok, "hello"})
2
iex(1)> tuple = {:ok, 1, "hello"}
{:ok, 1, "hello"}
iex(2)> tuple_size(tuple)
3

Functions for working

Accessing a tuple element with elem/2, put_elem/3, and tuple_size/1.

  • elem/2(tuple, index)

    Gets the element at the zero-based index in tuple. Raises ArgumentError when the index is negative or out of range of the tuple elements.

  • put_elem/3(tuple, index, value)

    Puts value at the given zero-based index in tuple.

  • tuple_size/1(tuple)

    Returns the size of a tuple, which is the number of elements in the tuple.

iex(1)> tuple = {:ok, 1, "hello"}
{:ok, 1, "hello"}
iex(2)> elem(tuple, 1)
1

iex> elem({:ok, "hello", 1}, 1)
"helo"
iex> elem({}, 0)
** (ArgumentError) argument error
iex> elem({:foo, :bar}, 2) 
** (ArgumentError) argument error

iex> put_elem({:foo, :ok, 3}, 2, 4)
{:foo, :ok, 4}
iex(1)> tuple = {:foo, :bar, 3}
iex(2)> put_elem(tuple, 0, :baz)
{:baz, :bar, 3}

iex(1)> tuple = {:ok, 1, "hello"}
{:ok, 1, "hello"}
iex(2)> tuple_size(tuple)
3

File.read/1

The File module is an interface module that provides an interface to the file system. The read(path) function returns a tuple with the atom :ok as the first element and the file contents as the second. Elixir allows us to pattern match on tagged tuples and effortlessly handle both success and failure cases.

iex> File.read("path/to/existing/file")
{:ok, "... contents ..."}
iex> File.read("path/to/unknown/file")
{:error, :enoent}

What is the difference between lists and tuples?

Lists and Tuples?

iex > list = [1, 2, 3] 
[1, 2, 3]

# This is fast as we only need to traverse `[0]` to prepend to `list` 
iex > [0] ++ list [0, 1, 2, 3]

# This is slow as we need to traverse `list` to append 4
iex > list ++ [4] [1, 2, 3, 4]
#When you update a tuple, all entries are shared between the old and the new tuple, except for the entry that has been replaced
iex >tuple = {:a, :b, :c, :d}
{:a, :b, :c, :d}

iex >put_elem(tuple, 2, :e)
{:a, :b, :e, :d}

Final Thoughts

This wraps up today's introduction to collection data types in Elixir: Lists and Tuples. If you haven't read the previous article, Basic types in Elixir, be sure to check it out. Our next article will delve into Pattern matching and The pin operator. Make sure not to miss it. I hope this article helps you. See you next time, bye!


This content originally appeared on DEV Community and was authored by Rhaenyra


Print Share Comment Cite Upload Translate Updates
APA

Rhaenyra | Sciencx (2024-06-23T12:54:49+00:00) Lists and tuples in Elixir. Retrieved from https://www.scien.cx/2024/06/23/lists-and-tuples-in-elixir/

MLA
" » Lists and tuples in Elixir." Rhaenyra | Sciencx - Sunday June 23, 2024, https://www.scien.cx/2024/06/23/lists-and-tuples-in-elixir/
HARVARD
Rhaenyra | Sciencx Sunday June 23, 2024 » Lists and tuples in Elixir., viewed ,<https://www.scien.cx/2024/06/23/lists-and-tuples-in-elixir/>
VANCOUVER
Rhaenyra | Sciencx - » Lists and tuples in Elixir. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/23/lists-and-tuples-in-elixir/
CHICAGO
" » Lists and tuples in Elixir." Rhaenyra | Sciencx - Accessed . https://www.scien.cx/2024/06/23/lists-and-tuples-in-elixir/
IEEE
" » Lists and tuples in Elixir." Rhaenyra | Sciencx [Online]. Available: https://www.scien.cx/2024/06/23/lists-and-tuples-in-elixir/. [Accessed: ]
rf:citation
» Lists and tuples in Elixir | Rhaenyra | Sciencx | https://www.scien.cx/2024/06/23/lists-and-tuples-in-elixir/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.