# Enum
```elixir
Mix.install([
{:jason, "~> 1.4"},
{:kino, "~> 0.9", override: true},
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"},
{:smart_animation, github: "brooklinjazz/smart_animation"},
{:visual, github: "brooklinjazz/visual"}
])
```
## Navigation
<div style="display: flex; align-items: center; width: 100%; justify-content: space-between; font-size: 1rem; color: #61758a; background-color: #f0f5f9; height: 4rem; padding: 0 1rem; border-radius: 1rem;">
<div style="display: flex;">
<i class="ri-home-fill"></i>
<a style="display: flex; color: #61758a; margin-left: 1rem;" href="../start.livemd">Home</a>
</div>
<div style="display: flex;">
<i class="ri-bug-fill"></i>
<a style="display: flex; color: #61758a; margin-left: 1rem;" href="https://github.com/DockYard-Academy/curriculum/issues/new?assignees=&labels=&template=issue.md&title=Enum">Report An Issue</a>
</div>
<div style="display: flex;">
<i class="ri-arrow-left-fill"></i>
<a style="display: flex; color: #61758a; margin-left: 1rem;" href="../reading/ranges.livemd">Ranges</a>
</div>
<div style="display: flex;">
<a style="display: flex; color: #61758a; margin-right: 1rem;" href="../exercises/fizzbuzz.livemd">FizzBuzz</a>
<i class="ri-arrow-right-fill"></i>
</div>
</div>
## Review Questions
Upon completing this lesson, a student should be able to answer the following questions.
* When and why might we use enumeration in programming?
* How do we transform every element in an enumerable?
* How do we remove elements from an enumerable?
* How do we use every element in an enumerable to build an acculumator and return a transformed value?
## Overview
### Enumeration
Enumeration is the act of looping through elements. Unlike iteration, which you may have encountered in other programming languages, enumeration does not allow you to change (mutate) elements in the original collection.
For example, we could enumerate through a list of numbers from one to five, and transform them into a new list of doubled numbers.
```mermaid
flowchart
subgraph Original
direction LR
1 --- 2 --- 3 --- 4 --- 5
end
subgraph Transformed
direction LR
T2[2] --- T4[4] --- T6[6] --- T8[8] --- T10[10]
end
Original --> Transformed
```
<!-- livebook:{"break_markdown":true} -->
### [Enum](https://hexdocs.pm/elixir/Enum.html)
The Elixir [Enum](https://hexdocs.pm/elixir/Enum.html) module contains functions for using enumeration with enumerable data structures.
For example, there is the [Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) function for applying a transformation function to each element in an enumerable.
```elixir
Enum.map([1, 2, 3, 4, 5], fn element -> element * 2 end)
```
### Enumerable
Certain data types in Elixir implement the [Enumerable](https://hexdocs.pm/elixir/Enumerable.html) protocol. That means we can enumerate through elements in these enumerable data types.
Most enumerables are collections, but not all of them. For example a range doesn't contain other elements, but it is enumerable.
```elixir
Enum.map(1..5, fn element -> element * 2 end)
```
### Collections
Data types that store other elements are often referred to as **collections**. For example, maps, lists, keyword lists, and tuples are all collections.
Many collections are enumerable, but not all of them. For example, a tuple is not enumerable.
<!-- livebook:{"break_markdown":true} -->
### Map, Filter, And Reduce
[Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2), [Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2), and [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) are the most common functions for enumeration. By understanding these functions and when to use them, you'll be able to solve most enumeration problems.
* [Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) returns the same number of elements with a transformation applied to each.
<!-- livebook:{"break_markdown":true} -->
```mermaid
flowchart
subgraph map
direction LR
subgraph input
direction LR
im1((1)) --> im2((2)) --> im3((3))
end
subgraph output
direction LR
om1[2] --> om2[4] --> om3[6]
end
input --"Enum.map(1..3, fn el -> el * 2 end)"--> output
end
```
```elixir
Enum.map(1..3, fn el -> el * 2 end)
```
* [Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2) removes element(s) from an enumerable without transforming them.
<!-- livebook:{"break_markdown":true} -->
```mermaid
flowchart
subgraph map
direction LR
subgraph input
direction LR
im1((1)) --> im2((2)) --> im3((3))
end
subgraph output
direction LR
om1((1)) --> om2((2))
end
input --"Enum.filter(1..3, fn el -> el <= 2 end)"--> output
end
```
```elixir
Enum.filter(1..3, fn el -> el <= 2 end)
```
* [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) uses the elements in an enumerable to build an accumulated value and return a transformed data structure.
```mermaid
flowchart
subgraph map
direction LR
subgraph input
direction LR
im1((1)) --> im2((2)) --> im3((3))
end
subgraph output
direction LR
om1[[6]]
end
input --"Enum.reduce(1..3, fn el, acc -> acc + el end)"--> output
end
```
```elixir
Enum.reduce(1..3, fn el, acc -> acc + el end)
```
## Scenario
Often while programming, you run into problems where you need the ability
to do something many many times.
For example, let's say you're creating a shopping application.
In this application, customers create a shopping list.
We'll represent this shopping cart as a list of item costs in pennies.
```elixir
shopping_cart = [100, 200, 150, 200]
```
We can create a function that will calculate the after tax cost of an item called `calculate_tax/1`. Lets say that the tax is `5%` so we can multiply our cost by `1.05`.
```elixir
calculate_tax = fn cost -> cost * 1.05 end
```
With four items in our shopping list, it's a bit tedius to call the `calculate_tax/1` function on each item. We'd need to bind each item to a variable and call the `calculate_tax/1` function on each item individually to determine the after tax cost of each item.
```elixir
[one, two, three, four] = shopping_cart
[calculate_tax.(one), calculate_tax.(two), calculate_tax.(three), calculate_tax.(four)]
```
This only works when there are exactly four items. If we want to handle when there is one, two, three, or four items our code gets much more verbose. As you can imagine, this solution is not scalable.
```elixir
shopping_cart = [100, 200, 150]
case shopping_cart do
[] ->
[]
[one] ->
[calculate_tax.(one)]
[one, two] ->
[calculate_tax.(one), calculate_tax.(two)]
[one, two, three] ->
[calculate_tax.(one), calculate_tax.(two), calculate_tax.(three)]
[one, two, three, four] ->
[calculate_tax.(one), calculate_tax.(two), calculate_tax.(three), calculate_tax.(four)]
end
```
To solve this problem, we need to apply the `calculate_tax/1` function on every element in the list. Any time we need to repeat a similar action over and over again we can use **enumeration**.
Enumeration is the act of looping through a collection and reading
its elements for the sake of returning some output.
<!-- livebook:{"break_markdown":true} -->
```mermaid
flowchart LR
Input ---> Enumeration --> Function --> Enumeration
Enumeration --> Output
```
<!-- livebook:{"break_markdown":true} -->
With enumeration, we can `calculate_tax/1` on any number of items with a single call to [Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2).
```elixir
shopping_cart = [100, 200, 150]
Enum.map(shopping_cart, fn item -> calculate_tax.(item) end)
```
## The Enum Module
Elixir provides the [Enum](https://hexdocs.pm/elixir/Enum.html) to accomplish enumeration. The [Enum](https://hexdocs.pm/elixir/Enum.html) module contains a large amount of useful functions that all work on collection data types such as lists, ranges, maps, and keyword lists.
Most enumeration problems can be solved with the following [Enum](https://hexdocs.pm/elixir/Enum.html) functions.
* [Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) enumerate over every element and create a new collection with a new value.
* [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) and [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3). Enumerate over every element into an accumulated value.
* [Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2) filter out elements from a collection.
<!-- livebook:{"break_markdown":true} -->
[Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) applies the callback function on every element in a collection to build a new list.
Each element in the new list will be the return value of the provided callback function.
```elixir
Enum.map(1..10, fn element -> element * 2 end)
```
[Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2) applies the callback function to every element in the collection and keeps an element when the callback function returns `true`.
```elixir
Enum.filter(1..10, fn element -> rem(element, 2) == 0 end)
```
[Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) and [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3) applies the callback function to every element in the collection and builds an accumulated value stored between each function call.
When complete, it returns the result of the last function call, which is typically the accumulated value
```elixir
# 0 Is The Initial Accumulator Value
Enum.reduce(1..3, 0, fn element, accumulator ->
element + accumulator
end)
```
[Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) uses the first value in the collection as the initial accumulator. Generally (but not always) [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3) is preferable for the sake of clarity, and we will prefer it for most use cases.
```elixir
Enum.reduce(1..3, 5, fn element, accumulator ->
element + accumulator
end)
```
```elixir
Enum.reduce(1..3, fn element, accumulator ->
element + accumulator
end)
```
### Other Handy Functions
The [Enum](https://hexdocs.pm/elixir/Enum.html) module also provides other useful functions. Here are a handful of the most used.
* [Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) check if all elements in a collection match some condition.
* [Enum.any?/2](https://hexdocs.pm/elixir/Enum.html#any?/2) check if any elements in a collection match some condition.
* [Enum.count/2](https://hexdocs.pm/elixir/Enum.html#count/2) return the number of elements in a collection collection.
* [Enum.find/3](https://hexdocs.pm/elixir/Enum.html#find/3) return an element in a collection that matches some condition.
* [Enum.random/1](https://hexdocs.pm/elixir/Enum.html#random/1) return a random element in a collection.
Anytime we're working with a collection, we should refer to the [Enum](https://hexdocs.pm/elixir/Enum.html) module to see if it has a built-in solution we can use. Alternatively, we can build nearly all functionality using only [Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2), [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3), and [Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) so consider developing the most familiarity with these three functions.
## Enum.map/2
[Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) allows you to enumerate through the collection you provide it as its first argument. It then calls a function that you provide it as its second argument on each element. Finally it returns a new collection with the modified values.
```mermaid
flowchart LR
A[Collection] --> E[Enum.map]
E --> Function
Function --> E
E --> B[New Collection]
```
Here's an example that doubles all the integers in a list.
```elixir
Enum.map([1, 2, 3, 4], fn integer -> integer * 2 end)
```
```mermaid
flowchart LR
A["[1, 2, 3, 4]"] --> E[Enum.map]
E --> F["fn integer -> integer * 2 end"]
F --> E
E --> B["[2, 4, 6, 8]"]
```
<!-- livebook:{"break_markdown":true} -->
It's useful to be aware that you can use ranges with enumerables to easily enumerate over large
ranges without needing to define every element in the list.
```elixir
Enum.map(1..100, fn integer -> integer * 2 end)
```
[Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) accepts any enumerable, and always returns a list, regardless of the input.
**keyword lists** and **maps** will be treated as lists of tuples for the sake of enumeration.
```elixir
Enum.map(%{"one" => 1, "two" => 2}, fn element -> element end)
```
```elixir
Enum.map([one: 1, two: 2], fn element -> element end)
```
We can even pattern match on the key and value in the tuple.
```elixir
Enum.map(%{"one" => 1, "two" => 2}, fn {_key, value} -> value end)
```
```elixir
Enum.map([one: 1, two: 2], fn {key, _value} -> key end)
```
### Your Turn
Use [Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) to convert a list of integers from `1` to `10` to strings.
<!-- livebook:{"force_markdown":true} -->
```elixir
# Expected Output
["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
```
<details style="background-color: lightgreen; padding: 1rem; margin: 1rem 0;">
<summary>Example Solution</summary>
```elixir
Enum.map(1..10, fn integer -> "#{integer}" end)
```
</details>
Enter your solution below.
```elixir
```
## Enum.reduce/2 And Enum.reduce/3
[Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) allows you to enumerate over a collection and build up an accumulated value with each enumeration.
Unlike [Enum.map/2](https://hexdocs.pm/elixir/Enum.html#map/2) this gives you significantly more control over your output, as the data type of the accumulator and return value do not have to be a list.
```mermaid
flowchart LR
A[Collection] --> E[Enum.reduce]
E -- Accumulator --> Function
Function -- Accumulator --> E
E --Final Accumulator--> B[Output]
```
<!-- livebook:{"break_markdown":true} -->
For example, we can sum all of the numbers in a list by building up an accumulated sum.
```elixir
list = [1, 2, 3, 4]
Enum.reduce(list, fn integer, accumulator -> integer + accumulator end)
```
The function you provide as the second argument of [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) will be called with the current element, and current accumulator.
The first value in the collection will be the initial accumulator value.
<!-- livebook:{"attrs":{"source":"frames = [\n \"\nFirst, we define the call the [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) function with a list, and a function.\n```elixir\nEnum.reduce([1, 2, 3, 4], fn integer, accumulator -> integer + accumulator end)\n```\n\",\n \"\nThe first element in the list `1` is the initial accumulator value.\n```elixir\nEnum.reduce([2, 3, 4], fn integer, 1 -> integer + 1 end)\n```\n\",\n \"\nThe function is called on the next element `2`. The next accumulator is 2 + 1\n```elixir\nEnum.reduce([3, 4], fn 2, 1 -> 2 + 1 end)\n```\n\",\n \"\nThe function is called on the next element `3`. The next accumulator is 3 + 3\n```elixir\nEnum.reduce([4], fn 3, 3 -> 3 + 3 end)\n```\n\",\n \"\nThe function is called on the next element `4`. The next accumulator is 4 + 6\n```elixir\nEnum.reduce([], fn 4, 6 -> 4 + 6 end)\n```\n\",\n \"\n4 + 6 equals 10.\n```elixir\nEnum.reduce([], fn 4, 6 -> 10 end)\n```\n\",\n \"\n`10` is the last accumulator value, so [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) returns `10`.\n```elixir\n 10\n```\n\"\n ]\n\nSmartAnimation.new(0..Enum.count(frames) - 1, fn i ->\n Kino.Markdown.new(Enum.at(frames, i))\nend)","title":"Reduce"},"chunks":null,"kind":"Elixir.HiddenCell","livebook_object":"smart_cell"} -->
````elixir
frames = [
"
First, we define the call the [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) function with a list, and a function.
```elixir
Enum.reduce([1, 2, 3, 4], fn integer, accumulator -> integer + accumulator end)
```
",
"
The first element in the list `1` is the initial accumulator value.
```elixir
Enum.reduce([2, 3, 4], fn integer, 1 -> integer + 1 end)
```
",
"
The function is called on the next element `2`. The next accumulator is 2 + 1
```elixir
Enum.reduce([3, 4], fn 2, 1 -> 2 + 1 end)
```
",
"
The function is called on the next element `3`. The next accumulator is 3 + 3
```elixir
Enum.reduce([4], fn 3, 3 -> 3 + 3 end)
```
",
"
The function is called on the next element `4`. The next accumulator is 4 + 6
```elixir
Enum.reduce([], fn 4, 6 -> 4 + 6 end)
```
",
"
4 + 6 equals 10.
```elixir
Enum.reduce([], fn 4, 6 -> 10 end)
```
",
"
`10` is the last accumulator value, so [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) returns `10`.
```elixir
10
```
"
]
SmartAnimation.new(0..(Enum.count(frames) - 1), fn i ->
Kino.Markdown.new(Enum.at(frames, i))
end)
````
### Enum.reduce/3
Alternatively, we can provide a default value for the accumulator with [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3).
[Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3) will call the function on every element, rather than setting the initial accumulator as the first element. Below, we sum all of the numbers in the list, with an initial sum of `10`.
```elixir
Enum.reduce([1, 2, 3], 10, fn integer, accumulator -> integer + accumulator end)
```
### Your Turn
Use [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3) or [Enum.reduce/2](https://hexdocs.pm/elixir/Enum.html#reduce/2) to sum all of the even numbers from `1` to `10`. It should return `30`.
<!-- livebook:{"force_markdown":true} -->
```elixir
2 + 4 + 6 + 8 + 10 = 30
```
<details style="background-color: lightgreen; padding: 1rem; margin: 1rem 0;">
<summary>Example solution</summary>
```elixir
Enum.reduce(1..10, 0, fn int, acc ->
if rem(int, 2) == 0 do
acc + int
else
acc
end
end)
```
</details>
Enter your solution below.
```elixir
```
## Enum.filter
The [Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2) function allows us to filter elements in a collection. [Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2) calls the function with each element in the collection. If the function returns `false` then the element is filtered out.
```mermaid
flowchart LR
C[Collection] --> E[Enum.filter]
E --> F[Function]
F -- boolean --> E
F --> true --> A[Keep]
F --> false --> B[Remove]
E --> O[Filtered Collection]
```
```elixir
Enum.filter([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], fn integer -> integer <= 5 end)
```
### Your Turn
use [Enum.filter/2](https://hexdocs.pm/elixir/Enum.html#filter/2) to create a list of odd numbers from `1` to `10` and a list of even numbers from `1` to `10`.
<details style="background-color: lightgreen; padding: 1rem; margin: 1rem 0;">
<summary>Example Solution</summary>
```elixir
even_numbers = Enum.filter(1..10, fn integer -> rem(integer, 2) == 0 end)
odd_numbers = Enum.filter(1..10, fn integer -> rem(integer, 2) != 0 end)
```
</details>
Enter your solution below.
```elixir
```
## Enum.all?/2
[Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) checks that all elements in a collection match some condition.
[Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) executes the callback function provided on each element. If every element returns truthy, then [Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) returns `true`.
<!-- livebook:{"break_markdown":true} -->
```mermaid
flowchart LR
Collection --> E[Enum.all?/2]
E --> Function
Function -- truthy --> E
E --> Boolean
```
```elixir
Enum.all?([1, 2, 3], fn integer -> is_integer(integer) end)
```
If a single element returns a falsy value, then [Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) returns `false`.
```elixir
Enum.all?([1, 2, 3, "4"], fn element -> is_integer(element) end)
```
For performance reasons, [Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) will complete as soon as it finds a single element that returns a falsey value when called with the function.
Notice the code below should finish very quickly because the very first element fails the condition.
```elixir
Enum.all?(1..10_000_000, fn integer -> is_bitstring(integer) end)
```
If [Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) must traverse the entire collection if all elements pass the condition, or if a failing element is towards the end of the list.
Notice the code below should take awhile to finish running because every element passes the condition.
```elixir
Enum.all?(1..10_000_000, fn integer -> is_integer(integer) end)
```
### Your Turn
Use [Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2) to determine if all of the `colors` in this list of colors are `:green`. You may change the value of `colors` to experiment with [Enum.all?/2](https://hexdocs.pm/elixir/Enum.html#all?/2).
```elixir
colors = [:green, :green, :red]
```
## Enum.any?/2
[Enum.any?/2](https://hexdocs.pm/elixir/Enum.html#any?/2) checks if any elements in a collection pass some condition. If a single element returns a truthy value when called with the callback function, then [Enum.any?/2](https://hexdocs.pm/elixir/Enum.html#any?/2) returns `true`.
<!-- livebook:{"break_markdown":true} -->
```mermaid
flowchart LR
Collection --> E[Enum.any?/2]
E --> Function
Function -- truthy --> E
E --> Boolean
```
```elixir
Enum.any?([1, "2", "3"], fn element -> is_integer(element) end)
```
[Enum.any?/2](https://hexdocs.pm/elixir/Enum.html#any?/2) returns as soon as an element in the collection returns a truthy value.
Notice the code below finishes very quickly, because the first element in the collection passes the condition.
```elixir
Enum.any?(1..10_000_000, fn integer -> is_integer(integer) end)
```
However, the following takes awhile to run because all elements in the collection fail the condition.
```elixir
Enum.any?(1..10_000_000, fn integer -> is_bitstring(integer) end)
```
### Your Turn
Use [Enum.any?/2](https://hexdocs.pm/elixir/Enum.html#any?/2) to determine if any of the animals in the `animals` list are `:dogs`. You may change the `animals` list to experiment with [Enum.any?/2](https://hexdocs.pm/elixir/Enum.html#any?/2).
```elixir
animals = [:cats, :dogs, :bears, :lions, :penguins]
```
## Enum.count/1
[Enum.count/1](https://hexdocs.pm/elixir/Enum.html#count/1) returns the number of items in a collection.
```mermaid
flowchart LR
Collection --> Enum.count --> Integer
```
```elixir
Enum.count([1, 2, 3])
```
The type of elements does not matter. Collections with multiple elements still only count as a single individual element.
```elixir
Enum.count([{}, "hello", %{}, [[[]]]])
```
### Your Turn
In the Elixir cell below, count the number of elements in the `collection`. It should return `5`.
```elixir
collection = [1, 2, 3, 4, 5]
```
## Enum.find/3
[Enum.find/3](https://hexdocs.pm/elixir/Enum.html#find/3) takes in a collection and a function. Then searches the collection and returns the first element that returns true when called as the argument to the passed-in function.
```elixir
Enum.find(["hello", 2, 10], fn each -> is_integer(each) end)
```
If no element is found, [Enum.find/2](https://hexdocs.pm/elixir/Enum.html#find/2) returns `nil`.
```elixir
Enum.find(["h", "e", "l", "l", "o"], fn each -> is_integer(each) end)
```
You might notice the arity of the function is `3` even though we passed in only `2` arguments. That's because there's an optional `default` value argument. The `default` value will be returned instead of `nil` if no element is found.
```elixir
Enum.find(["h", "e", "l", "l", "o"], 10, fn each -> is_integer(each) end)
```
### Your Turn
Use [Enum.find/2](https://hexdocs.pm/elixir/Enum.html#find/2) to find the first even integer in this list.
```elixir
[1, "2", "three", 4, "five", 6]
```
## Enum.random/1
[Enum.random/1](https://hexdocs.pm/elixir/Enum.html#random/1) returns a random element in a collection. It's often used to generate random numbers in a range.
```elixir
Enum.random(1..10)
```
### Your Turn
Generate a list with ten random integers from `0` to `9`.
<details style="background-color: lightgreen; padding: 1rem; margin: 1rem 0;">
<summary>Example solution</summary>
```elixir
Enum.map(1..10, fn _ -> Enum.random(0..9) end)
```
</details>
Enter your solution below.
```elixir
```
## Capture Operator And Module Functions
When we provide a function to any of the [Enum](https://hexdocs.pm/elixir/Enum.html) we're passing an anonymous function, which will be called under the hood.
We'll bind this function to a variable and inspect every value to demonstrate.
```elixir
my_function = fn element -> IO.inspect(element) end
Enum.map(1..10, my_function)
```
We can use the capture operator `&` syntax to provide module functions.
```elixir
defmodule NonAnonymous do
def function(element) do
IO.inspect(element)
end
end
Enum.map(1..10, &NonAnonymous.function/1)
```
This can be used with any of Elixir's built-in functions as well, as long as their arity matches the callback function.
```elixir
Enum.map(1..10, &is_integer/1)
```
We can also use the capture operator alone to create an anonymous function. However, we generally don't recommend this as it typically reduces readability. `&1` is the first argument to the function.
```elixir
Enum.map(1..10, &(&1 * 2))
```
## Further Reading
The [Enum](https://hexdocs.pm/elixir/Enum.html) module has many more functions. You'll have the opportunity to encounter more as you need them to solve future challenges.
For more information, you may also wish to read:
* [The Enum Documentation](https://hexdocs.pm/elixir/Enum.html)
* [Elixir Schools Enum](https://elixirschool.com/en/lessons/basics/enum)
We have several exercises dedicated to the [Enum](https://hexdocs.pm/elixir/Enum.html) module as part of this curriculum. However, if you wish for more practice [Exercism.io](https://exercism.org/tracks/elixir/concepts/enum) has a number of excellent exercises.
## Commit Your Progress
DockYard Academy now recommends you use the latest [Release](https://github.com/DockYard-Academy/curriculum/releases) rather than forking or cloning our repository.
Run `git status` to ensure there are no undesirable changes.
Then run the following in your command line from the `curriculum` folder to commit your progress.
```
$ git add .
$ git commit -m "finish Enum reading"
$ git push
```
We're proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.
We also offer a paid course where you can learn from an instructor alongside a cohort of your peers.
We will accept applications for the June-August 2023 cohort soon.
## Navigation
<div style="display: flex; align-items: center; width: 100%; justify-content: space-between; font-size: 1rem; color: #61758a; background-color: #f0f5f9; height: 4rem; padding: 0 1rem; border-radius: 1rem;">
<div style="display: flex;">
<i class="ri-home-fill"></i>
<a style="display: flex; color: #61758a; margin-left: 1rem;" href="../start.livemd">Home</a>
</div>
<div style="display: flex;">
<i class="ri-bug-fill"></i>
<a style="display: flex; color: #61758a; margin-left: 1rem;" href="https://github.com/DockYard-Academy/curriculum/issues/new?assignees=&labels=&template=issue.md&title=Enum">Report An Issue</a>
</div>
<div style="display: flex;">
<i class="ri-arrow-left-fill"></i>
<a style="display: flex; color: #61758a; margin-left: 1rem;" href="../reading/ranges.livemd">Ranges</a>
</div>
<div style="display: flex;">
<a style="display: flex; color: #61758a; margin-right: 1rem;" href="../exercises/fizzbuzz.livemd">FizzBuzz</a>
<i class="ri-arrow-right-fill"></i>
</div>
</div>