Introduction
The Enum module is your Swiss-army knife for working with collections.
Anything a for loop would do in another language (transform, filter,
group, sort, add up, pick an element) you do in Elixir with a function
from Enum.
The big idea is always the same: Enum takes a collection and a small
function that describes what to do with each element, and gives you back
a new collection or a single value.
Consider this example of using Enum to multiply each element in a list
by 2:
list = [1, 2, 3, 4]
Enum.map(list, fn x -> x * 2 end)
# => [2, 4, 6, 8]
The Enum.map function takes two arguments: the enumerable (list in this case) and a transformation function for each element.
For further enhancement, Elixir’s pipe operator (|>) can be used with Enum functions for cleaner and more readable code. Here’s an example:
list = [1, 2, 3, 4]
list
|> Enum.map(fn x -> x * 3 end)
|> Enum.filter(fn x -> rem(x, 2) == 0 end)
# => [6, 12]
This statement takes a list, multiplies each element by 3 using Enum.map, and then filters out the odd numbers using Enum.filter. The use of the pipe operator makes the code flow naturally and easier to read.
|
You can also use the
|
Enum functions are eager; they execute immediately and return a result. If memory usage is a concern with very large collections, consider using the Stream module for lazy computation.
|
Commonly Used Enum Functions
Enum offers a ton of useful functions. All are listed at the official Enum documentation. Here are some of the most commonly used functions to give you an idea of what’s available.
Enum.map/2
The Enum.map/2 function is used to transform each element in an enumerable using a provided function.
list = [1, 2, 3, 4]
Enum.map(list, fn x -> x * 2 end)
# => [2, 4, 6, 8]
The &1 shorthand can be used as follows:
list = [1, 2, 3, 4]
list |> Enum.map(&(&1 * 2))
# => [2, 4, 6, 8]
More details can be found at the official Elixir Enum.map/2 documentation.
Enum.filter/2
The Enum.filter/2 function filters out elements based on a provided function.
list = [1, nil, 2, nil, 3]
Enum.filter(list, fn x -> x != nil end)
# => [1, 2, 3]
Using the &1 shorthand:
list = [1, nil, 2, nil, 3]
list |> Enum.filter(&(&1 != nil))
# => [1, 2, 3]
More details can be found at the official Elixir Enum.filter/2 documentation.
Enum.reduce/2,3
The Enum.reduce/2,3 function reduces an enumerable to a single value.
list = [1, 2, 3, 4]
Enum.reduce(list, 0, fn x, acc -> x + acc end)
# => 10
The use of reduce/3 and it’s accumulator is similar to the fold function in other languages. It can be tricky to use.
|
More details can be found at the official Elixir Enum.reduce/2 documentation.
Enum.sort/1,2
The Enum.sort/1,2 function sorts the elements in an enumerable.
list = [4, 2, 3, 1]
Enum.sort(list)
# => [1, 2, 3, 4]
You can provide a comparator function:
list = [4, 2, 3, 1]
Enum.sort(list, fn a, b -> a > b end)
# => [4, 3, 2, 1]
More details can be found at the official Elixir Enum.sort/2 documentation.
Enum.at/2,3
Returns the element at the given index (zero based) or a default value.
list = [1, 2, 3, 4]
Enum.at(list, 2)
# Output: 3
More details can be found at the official Elixir Enum.at/2,3 documentation.
Enum.concat/1,2
Concatenates the collection of enumerable(s) given.
Enum.concat([[1, 2], [3, 4]])
# Output: [1, 2, 3, 4]
More details can be found at the official Elixir Enum.concat/1,2 documentation.
Enum.count/1,2
Counts the enumerable items, optionally, using the provided function.
list = [1, 2, 3, 4]
Enum.count(list)
# Output: 4
More details can be found at the official Elixir Enum.count/1,2 documentation.
Enum.find/2,3
Finds the first element for which the provided function returns a truthy value.
list = [1, 2, 3, 4]
Enum.find(list, fn x -> x > 2 end)
# Output: 3
More details can be found at the official Elixir Enum.find/2,3 documentation.
Enum.group_by/2,3
Groups all items in the enumerable by the given function.
list = [{:apple, "fruit"}, {:carrot, "vegetable"}, {:banana, "fruit"}]
Enum.group_by(list, fn {_name, type} -> type end)
# %{
# "fruit" => [apple: "fruit", banana: "fruit"],
# "vegetable" => [carrot: "vegetable"]
# }
IEx prints {:apple, "fruit"} as apple: "fruit" when every
element in the list is a two-tuple starting with an atom, that is just
the keyword list syntax. The data is still a list of tuples, the
display is nicer to read.
|
More details can be found at the official Elixir Enum.group_by/2,3 documentation.
Enum.join/1,2
Joins all the items in the enumerable into a single string.
list = ["Hello", "World"]
Enum.join(list, " ")
# Output: "Hello World"
More details can be found at the official Elixir Enum.join/1,2 documentation.
Enum.max/1
Returns the maximum value in the enumerable.
list = [1, 2, 3, 4]
Enum.max(list)
# Output: 4
More details can be found at the official Elixir Enum.max/1 documentation.
Enum.min/1
Returns the minimum value in the enumerable.
list = [1, 2, 3, 4]
Enum.min(list)
# Output: 1
More details can be found at the official Elixir Enum.min/1 documentation.
Enum.random/1
Selects a random element from the enumerable.
list = [1, 2, 3, 4]
Enum.random(list)
# Output: Random value from the list
More details can be found at the official Elixir Enum.random/1 documentation.
Enum.reject/2
Filters out the items in the enumerable for which the provided function returns a truthy value.
list = [1, 2, 3, 4]
Enum.reject(list, fn x -> x < 3 end)
# Output: [3, 4]
More details can be found at the official Elixir Enum.reject/2 documentation.
Enum.sum/1
Returns the sum of all items in the enumerable.
list = [1, 2, 3, 4]
Enum.sum(list)
# Output: 10
More details can be found at the official Elixir Enum.sum/1 documentation.