Powered by AppSignal & Oban Pro

Enum

drills/enum.livemd

Enum

The Enum Module Review

The Enum module in Elixir provides a set of functions for working with collections of data, known as enumerables.

Enum.member?()

In this section, you will do drills with Enum.member?().

Drill 1: Find out if a target number is in a list of numbers.

target = 2
numbers = 1..100
Example Solution ```elixir Enum.member?(numbers, target) ```

Enum.map()

In this section, you will do drills with Enum.map() (“Enum.map/2” in Elixir arity-speak).

Drill 1: Use Enum.map/2 to double the values in a list.

list = [4, 265, 22, 9]
Enum.map(list, fn x -> x * 2 end)

Drill 2: Use Enum.map/2 to loop through a map and return a list of only the values from each key-value pair in person below.

person = %{name: "Izzy", age: "30ish", gender: "Female"}
Example Solution ```elixir Enum.map(person, fn {_key, value} -> value end) ```

Drill 3: Use Enum.map/2 to convert a list of temperatures from Celsius to Fahrenheit.

celsius = [4, 20, 32, 40, 22, 11]
Example Solution ```elixir Enum.map(celsius, fn temp -> temp * 1.8 + 32 end) ```

Drill 4: Use Enum.map/2 to evaluate a list of numbers, reporting :good or :bad based on whether each number is evenly divisible by 3.

Example Solution ```elixir Enum.map([1, 3, 11, 27, 42, 12, 8642, 9], fn num -> if rem(num, 3) == 0, do: :good, else: :bad end) ```

Drill 5: Use Enum.map/2 to transform as list of 5 numbers to a list with the word for each number.

Example Solution ```elixir Enum.map([1, 2, 3, 4, 5], fn num -> case num do 1 -> "one" 2 -> "two" 3 -> "three" 4 -> "four" 5 -> "five" end end) ```

Enum.filter()

In this section, you will do drills with Enum.filter() (“Enum.filter/2” in Elixir arity-speak). Enum.filter/2 is similar to Enum.map/2, except filter returns only those elements in the list which result in a “truthy” result of the anymous function (fn -> … end) evaluation.

Drill 1: Use Enum.filter/2 to evaluate a list of numbers and return a list of only the even numbers.

Example Solution ```elixir Enum.filter([1, 2, 3, 4, 5], fn num -> if rem(num, 2) == 0, do: num end) ```

Drill 2: Use Enum.filter/2 to evaluate a list of numbers, returning only the numbers that are “material.”

Materiality is an accounting concept about transactions being big enough to invest the time to fully track; an “immaterial” transaction is smaller than a “materiality threshold,” and is therefore not tracked. Your filter results will keep only the transactions big enough to bother tracking. Big enough (what is “material”) is up to you to decide.

Example Solution ```elixir Enum.filter([1000, 500, 750, 25_000, 450, 600], fn num -> if num >= 750, do: num end) ```

Drill 3: Use Enum.filter/2 to evaluate the key-value pairs (i.e., an Elixir Map) in family below, returning only the members of the list who are most likely parents.

family = %{mom: "Wilma", dad: "Fred", brother: "Bam-bam", sister: "Pebbles", pet: "Dino"}
Example Solution ```elixir # ONE solution ... not the most elegant: Enum.filter(family, fn {key, value} -> if key in [:mom, :dad], do: {key, value} end) |> Enum.into(%{}) ```

Drill 4: Use Enum.filter/2 to evaluate a list of … .

Drill 5: Use Enum.filter/2 to evaluate a list of … .

Enum.reduce()

In this section, you will do drills with Enum.reduce().

“Enum.reduce/3” is the more explicit form of the function. “Enum.reduce/2” uses the first item in the Enumeration as the starting accumulator.

Drill 1: Use Enum.reduce/3 to add all the numbers in a list.

numbers = [1, 2, 3, 4]
Example Solution ```elixir # reduce/3 explicitly requires an initial value for the accumulator: Enum.reduce(numbers, 0, fn x, acc -> x + acc end) ```

Drill 2: Use Enum.reduce/2 instead to add all the numbers in a list.

Example Solution ```elixir # reduce/2 uses the first element as the starting accumulator: Enum.reduce(numbers, fn a, b -> a + b end) ```

Drill 3: Use Enum.reduce/3 to remove duplicates.

Note that even though reduce returns a single variable - that variable can be a list.

letters = ['a', 'b', 'a', 'c', 'c', 'd']
# => ['a', 'b', 'c', 'd']
Example Solution ```elixir # the accumulator can be a list too: Enum.reduce(letters, [], fn letter, acc -> if Enum.member?(acc, letter) do acc else acc ++ [letter] end end) ```