Collections

Elixir lists, tuples, maps, keyword lists, MapSets, and Enum functions

Lists (linked lists)

Lists are linked lists — prepend is O(1), append and random access are O(n).

[1, 2, 3]             # literal
[1, 2] ++ [3, 4]      # concatenation => [1, 2, 3, 4]
[1 | [2, 3]]          # prepend => [1, 2, 3]
hd([1, 2, 3])          # => 1 (head)
tl([1, 2, 3])          # => [2, 3] (tail)
length([1, 2, 3])      # => 3

# Pattern matching
[head | tail] = [1, 2, 3]
head  # => 1
tail  # => [2, 3]

Tuples

Fixed-size, indexed collections. Fast random access by index.

{:ok, 42}              # 2-tuple (pair)
{1, 2, 3}             # 3-tuple

elem({:a, :b, :c}, 0) # => :a
put_elem({:a, :b}, 1, :x) # => {:a, :x}
tuple_size({1, 2, 3}) # => 3

Maps

Key-value store with fast lookup. Keys can be any type.

# Creating maps
m = %{a: 1, b: 2}              # atom keys
m = %{"a" => 1, "b" => 2}     # string keys

# Accessing
m.a                            # => 1 (atom keys only)
m[:a]                          # => 1 (any key, returns nil if missing)
Map.get(m, :a)                 # => 1
Map.get(m, :z, 0)              # => 0 (default value)

# Updating (returns new map)
%{m | a: 10}                   # => %{a: 10, b: 2}
Map.put(m, :c, 3)              # => %{a: 1, b: 2, c: 3}
Map.delete(m, :a)              # => %{b: 2}

# Pattern matching
%{a: value} = %{a: 1, b: 2}
value  # => 1

# Struct-like access
defmodule User do
  defstruct name: nil, age: 0
end

u = %User{name: "Alice", age: 30}
u.name  # => "Alice"
%{u | age: 31}  # => %User{name: "Alice", age: 31}

Common Map functions

Function Example Result
Map.new/1 Map.new([{:a, 1}]) %{a: 1}
Map.keys/1 Map.keys(%{a: 1, b: 2}) [:a, :b]
Map.values/1 Map.values(%{a: 1, b: 2}) [1, 2]
Map.has_key?/2 Map.has_key?(%{a: 1}, :a) true
Map.merge/2 Map.merge(%{a: 1}, %{b: 2}) %{a: 1, b: 2}
Map.to_list/1 Map.to_list(%{a: 1}) [a: 1]

Keyword lists

Ordered list of 2-tuples with atom keys. Often used for optional arguments.

[k1: "v1", k2: "v2"]  # => [k1: "v1", k2: "v2"]
Keyword.get([a: 1, b: 2], :a)  # => 1
Keyword.keys([a: 1, b: 2])     # => [:a, :b]
Keyword.values([a: 1, b: 2])   # => [1, 2]

Tip: Prefer maps over keyword lists for most use cases. Use keyword lists only when order matters (e.g., passing options to functions).

MapSet

Unordered collection of unique elements.

s = MapSet.new([1, 2, 3])
MapSet.put(s, 4)         # => #MapSet<[1, 2, 3, 4]>
MapSet.member?(s, 2)     # => true
MapSet.delete(s, 2)      # => #MapSet<[1, 3]>

# Set operations
a = MapSet.new([1, 2, 3])
b = MapSet.new([2, 3, 4])
MapSet.union(a, b)        # => #MapSet<[1, 2, 3, 4]>
MapSet.intersection(a, b) # => #MapSet<[2, 3]>
MapSet.difference(a, b)  # => #MapSet<[1]>

Ranges

1..10           # inclusive range
1..10//2        # step of 2 => [1, 3, 5, 7, 9]
Enum.to_list(1..5)  # => [1, 2, 3, 4, 5]