Skip to content

Latest commit

 

History

History
226 lines (159 loc) · 3.85 KB

File metadata and controls

226 lines (159 loc) · 3.85 KB

Elixir Koans - 14 Enums

import ExUnit.Assertions

Knowing how many elements are in a list is important for book-keeping

assert Enum.count([1, 2, 3]) == ___

Counting is similar to length

assert length([1, 2, 3]) == ___

But it allows you to count certain elements

assert Enum.count([1, 2, 3], &(&1 == 2)) == ___

Depending on the type, it counts pairs while length does not

map = %{a: :foo, b: :bar}
assert Enum.count(map) == ___
assert_raise ___, fn -> length(map) end

Elements can have a lot in common

def less_than_five?(n), do: n < 5
assert Enum.all?([1, 2, 3], &less_than_five?/1) == ___
assert Enum.all?([4, 6, 8], &less_than_five?/1) == ___

Sometimes you just want to know if there are any elements fulfilling a condition

def even?(n), do: rem(n, 2) == 0
assert Enum.any?([1, 2, 3], &even?/1) == ___
assert Enum.any?([1, 3, 5], &even?/1) == ___

Sometimes you just want to know if an element is part of the party

input = [1, 2, 3]
assert Enum.member?(input, 1) == ___
assert Enum.member?(input, 30) == ___

Mapping converts each element of a list by running some function with it

def multiply_by_ten(n), do: 10 * n
assert Enum.map([1, 2, 3], &multiply_by_ten/1) == ___

Filter allows you to only keep what you really care about

def odd?(n), do: rem(n, 2) == 1
assert Enum.filter([1, 2, 3], &odd?/1) == ___

Reject will help you throw out unwanted cruft

assert Enum.reject([1, 2, 3], &odd?/1) == ___

You three there, follow me!

assert Enum.take([1, 2, 3, 4, 5], 3) == ___

You can ask for a lot, but Enum won't hand you more than you give

assert Enum.take([1, 2, 3, 4, 5], 10) == ___

Just like taking, you can also drop elements

assert Enum.drop([-1, 0, 1, 2, 3], 2) == ___

Zip-up in pairs!

letters = [:a, :b, :c]
numbers = [1, 2, 3]
assert Enum.zip(letters, numbers) == ___

When you want to find that one pesky element, it returns the first

assert Enum.find([1, 2, 3, 4], &even?/1) == ___

...but you don't quite find it...

def divisible_by_five?(n), do: rem(n, 5) == 0
assert Enum.find([1, 2, 3], &divisible_by_five?/1) == ___

...you can settle for a consolation prize

assert Enum.find([1, 2, 3], :no_such_element, &divisible_by_five?/1) == ___

Collapse an entire list of elements down to a single one by repeating a function.

assert Enum.reduce([1, 2, 3], 0, fn element, accumulator -> element + accumulator end) == ___

Enum.chunk_every splits lists into smaller lists of fixed size

assert Enum.chunk_every([1, 2, 3, 4, 5, 6], 2) == ___
assert Enum.chunk_every([1, 2, 3, 4, 5], 3) == ___

Enum.flat_map transforms and flattens in one step

result =
  [1, 2, 3]
  |> Enum.flat_map(&[&1, &1 * 10])
assert result == ___

Enum.group_by organizes elements by a grouping function

words = ["apple", "banana", "cherry", "apricot", "blueberry"]
grouped = Enum.group_by(words, &String.first/1)
assert grouped["a"] == ___
assert grouped["b"] == ___

Stream provides lazy enumeration for large datasets

Streams are lazy - they don't execute until you call Enum on them

stream =
  1..1_000_000
  |> Stream.filter(&even?/1)
  |> Stream.map(&(&1 * 2))
  |> Stream.take(3)

Nothing has been computed yet!

result = Enum.to_list(stream)
assert result == ___

Next Steps