1023 lines
19 KiB
Plaintext
1023 lines
19 KiB
Plaintext
# Enum cheatsheet
|
|
|
|
A quick reference into the `Enum` module, a module for working with collections (known as enumerables). Most of the examples below use the following data structure:
|
|
|
|
```elixir
|
|
cart = [
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
Some examples use the [`string =~ part`](`=~/2`) operator, which checks the string on the left contains the part on the right.
|
|
|
|
## Predicates
|
|
{: .col-2}
|
|
|
|
### [`any?(enum, fun)`](`Enum.any?/2`)
|
|
|
|
```elixir
|
|
iex> Enum.any?(cart, & &1.fruit == "orange")
|
|
true
|
|
iex> Enum.any?(cart, & &1.fruit == "pear")
|
|
false
|
|
```
|
|
|
|
`any?` with an empty collection is always false:
|
|
|
|
```elixir
|
|
iex> Enum.any?([], & &1.fruit == "orange")
|
|
false
|
|
```
|
|
|
|
### [`all?(enum, fun)`](`Enum.all?/2`)
|
|
|
|
```elixir
|
|
iex> Enum.all?(cart, & &1.count > 0)
|
|
true
|
|
iex> Enum.all?(cart, & &1.count > 1)
|
|
false
|
|
```
|
|
|
|
`all?` with an empty collection is always true:
|
|
|
|
```elixir
|
|
iex> Enum.all?([], & &1.count > 0)
|
|
true
|
|
```
|
|
|
|
### [`member?(enum, value)`](`Enum.member?/2`)
|
|
|
|
```elixir
|
|
iex> Enum.member?(cart, %{fruit: "apple", count: 3})
|
|
true
|
|
iex> Enum.member?(cart, :something_else)
|
|
false
|
|
```
|
|
|
|
`item in enum` is equivalent to `Enum.member?(enum, item)`:
|
|
|
|
```elixir
|
|
iex> %{fruit: "apple", count: 3} in cart
|
|
true
|
|
iex> :something_else in cart
|
|
false
|
|
```
|
|
|
|
### [`empty?(enum)`](`Enum.empty?/1`)
|
|
|
|
```elixir
|
|
iex> Enum.empty?(cart)
|
|
false
|
|
iex> Enum.empty?([])
|
|
true
|
|
```
|
|
|
|
## Filtering
|
|
{: .col-2}
|
|
|
|
### [`filter(enum, fun)`](`Enum.filter/2`)
|
|
|
|
```elixir
|
|
iex> Enum.filter(cart, &(&1.fruit =~ "o"))
|
|
[%{fruit: "orange", count: 6}]
|
|
iex> Enum.filter(cart, &(&1.fruit =~ "e"))
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
### [`reject(enum, fun)`](`Enum.reject/2`)
|
|
|
|
```elixir
|
|
iex> Enum.reject(cart, &(&1.fruit =~ "o"))
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
]
|
|
```
|
|
|
|
### [`Comprehension`](`for/1`)
|
|
|
|
Filtering can also be done with comprehensions:
|
|
|
|
```elixir
|
|
iex> for item <- cart, item.fruit =~ "e" do
|
|
...> item
|
|
...> end
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
Pattern-matching in comprehensions acts as a filter as well:
|
|
|
|
```elixir
|
|
iex> for %{count: 1, fruit: fruit} <- cart do
|
|
...> fruit
|
|
...> end
|
|
["banana"]
|
|
```
|
|
|
|
## Mapping
|
|
{: .col-2}
|
|
|
|
### [`map(enum, fun)`](`Enum.map/2`)
|
|
|
|
```elixir
|
|
iex> Enum.map(cart, & &1.fruit)
|
|
["apple", "banana", "orange"]
|
|
iex> Enum.map(cart, fn item ->
|
|
...> %{item | count: item.count + 10}
|
|
...> end)
|
|
[
|
|
%{fruit: "apple", count: 13},
|
|
%{fruit: "banana", count: 11},
|
|
%{fruit: "orange", count: 16}
|
|
]
|
|
```
|
|
|
|
### [`map_every(enum, nth, fun)`](`Enum.map_every/3`)
|
|
|
|
```elixir
|
|
iex> Enum.map_every(cart, 2, fn item ->
|
|
...> %{item | count: item.count + 10}
|
|
...> end)
|
|
[
|
|
%{fruit: "apple", count: 13},
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 16}
|
|
]
|
|
```
|
|
|
|
### [`Comprehension`](`for/1`)
|
|
|
|
Mapping can also be done with comprehensions:
|
|
|
|
```elixir
|
|
iex> for item <- cart do
|
|
...> item.fruit
|
|
...> end
|
|
["apple", "banana", "orange"]
|
|
```
|
|
|
|
You can also filter and map at once:
|
|
|
|
```elixir
|
|
iex> for item <- cart, item.fruit =~ "e" do
|
|
...> item.fruit
|
|
...> end
|
|
["apple", "orange"]
|
|
```
|
|
|
|
## Side-effects
|
|
{: .col-2}
|
|
|
|
### [`each(enum, fun)`](`Enum.each/2`)
|
|
|
|
```elixir
|
|
iex> Enum.each(cart, &IO.puts(&1.fruit))
|
|
apple
|
|
banana
|
|
orange
|
|
:ok
|
|
```
|
|
|
|
`Enum.each/2` is used exclusively for side-effects.
|
|
|
|
## Accumulating
|
|
{: .col-2}
|
|
|
|
### [`reduce(enum, acc, fun)`](`Enum.reduce/3`)
|
|
|
|
```elixir
|
|
iex> Enum.reduce(cart, 0, fn item, acc ->
|
|
...> item.count + acc
|
|
...> end)
|
|
10
|
|
```
|
|
|
|
### [`map_reduce(enum, acc, fun)`](`Enum.map_reduce/3`)
|
|
|
|
```elixir
|
|
iex> Enum.map_reduce(cart, 0, fn item, acc ->
|
|
...> {item.fruit, item.count + acc}
|
|
...> end)
|
|
{["apple", "banana", "orange"], 10}
|
|
```
|
|
|
|
### [`scan(enum, acc, fun)`](`Enum.scan/3`)
|
|
|
|
```elixir
|
|
iex> Enum.scan(cart, 0, fn item, acc ->
|
|
...> item.count + acc
|
|
...> end)
|
|
[3, 4, 10]
|
|
```
|
|
|
|
### [`reduce_while(enum, acc, fun)`](`Enum.reduce_while/3`)
|
|
|
|
```elixir
|
|
iex> Enum.reduce_while(cart, 0, fn item, acc ->
|
|
...> if item.fruit == "orange" do
|
|
...> {:halt, acc}
|
|
...> else
|
|
...> {:cont, item.count + acc}
|
|
...> end
|
|
...> end)
|
|
4
|
|
```
|
|
|
|
### [`Comprehension`](`for/1`)
|
|
|
|
Reducing can also be done with comprehensions:
|
|
|
|
```elixir
|
|
iex> for item <- cart, reduce: 0 do
|
|
...> acc -> item.count + acc
|
|
...> end
|
|
10
|
|
```
|
|
|
|
You can also filter and reduce at once:
|
|
|
|
```elixir
|
|
iex> for item <- cart, item.fruit =~ "e", reduce: 0 do
|
|
...> acc -> item.count + acc
|
|
...> end
|
|
9
|
|
```
|
|
|
|
## Aggregations
|
|
{: .col-2}
|
|
|
|
### [`count(enum)`](`Enum.count/1`)
|
|
|
|
```elixir
|
|
iex> Enum.count(cart)
|
|
3
|
|
```
|
|
|
|
See `Enum.count_until/2` to count until a limit.
|
|
|
|
### [`frequencies(enum)`](`Enum.frequencies/1`)
|
|
|
|
```elixir
|
|
iex> Enum.frequencies(["apple", "banana", "orange", "apple"])
|
|
%{"apple" => 2, "banana" => 1, "orange" => 1}
|
|
```
|
|
|
|
### [`frequencies_by(enum, key_fun)`](`Enum.frequencies_by/2`)
|
|
|
|
Frequencies of the last letter of the fruit:
|
|
|
|
```elixir
|
|
iex> Enum.frequencies_by(cart, &String.last(&1.fruit))
|
|
%{"a" => 1, "e" => 2}
|
|
```
|
|
|
|
### [`count(enum, fun)`](`Enum.count/2`)
|
|
|
|
```elixir
|
|
iex> Enum.count(cart, &(&1.fruit =~ "e"))
|
|
2
|
|
iex> Enum.count(cart, &(&1.fruit =~ "y"))
|
|
0
|
|
```
|
|
|
|
See `Enum.count_until/3` to count until a limit with a function.
|
|
|
|
### [`sum(enum)`](`Enum.sum/1`)
|
|
|
|
```elixir
|
|
iex> cart |> Enum.map(& &1.count) |> Enum.sum()
|
|
10
|
|
```
|
|
|
|
### [`product(enum)`](`Enum.product/1`)
|
|
|
|
```elixir
|
|
iex> cart |> Enum.map(& &1.count) |> Enum.product()
|
|
18
|
|
```
|
|
|
|
## Sorting
|
|
{: .col-2}
|
|
|
|
### [`sort(enum, sorter \\ :asc)`](`Enum.sort/2`)
|
|
|
|
```elixir
|
|
iex> cart |> Enum.map(& &1.fruit) |> Enum.sort()
|
|
["apple", "banana", "orange"]
|
|
iex> cart |> Enum.map(& &1.fruit) |> Enum.sort(:desc)
|
|
["orange", "banana", "apple"]
|
|
```
|
|
|
|
When sorting structs, use `Enum.sort/2` with a module as sorter.
|
|
|
|
### [`sort_by(enum, mapper, sorter \\ :asc)`](`Enum.sort_by/2`)
|
|
|
|
```elixir
|
|
iex> Enum.sort_by(cart, & &1.count)
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
iex> Enum.sort_by(cart, & &1.count, :desc)
|
|
[
|
|
%{fruit: "orange", count: 6},
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
]
|
|
```
|
|
|
|
When the sorted by value is a struct, use `Enum.sort_by/3` with a module as sorter.
|
|
|
|
### [`min(enum)`](`Enum.min/1`)
|
|
|
|
```elixir
|
|
iex> cart |> Enum.map(& &1.count) |> Enum.min()
|
|
1
|
|
```
|
|
|
|
When comparing structs, use `Enum.min/2` with a module as sorter.
|
|
|
|
### [`min_by(enum, mapper)`](`Enum.min_by/2`)
|
|
|
|
```elixir
|
|
iex> Enum.min_by(cart, & &1.count)
|
|
%{fruit: "banana", count: 1}
|
|
```
|
|
|
|
When comparing structs, use `Enum.min_by/3` with a module as sorter.
|
|
|
|
### [`max(enum)`](`Enum.max/1`)
|
|
|
|
```elixir
|
|
iex> cart |> Enum.map(& &1.count) |> Enum.max()
|
|
6
|
|
```
|
|
|
|
When comparing structs, use `Enum.max/2` with a module as sorter.
|
|
|
|
### [`max_by(enum, mapper)`](`Enum.max_by/2`)
|
|
|
|
```elixir
|
|
iex> Enum.max_by(cart, & &1.count)
|
|
%{fruit: "orange", count: 6}
|
|
```
|
|
|
|
When comparing structs, use `Enum.max_by/3` with a module as sorter.
|
|
|
|
## Concatenating & flattening
|
|
{: .col-2}
|
|
|
|
### [`concat(enums)`](`Enum.concat/1`)
|
|
|
|
```elixir
|
|
iex> Enum.concat([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
|
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
```
|
|
|
|
### [`concat(left, right)`](`Enum.concat/2`)
|
|
|
|
```elixir
|
|
iex> Enum.concat([1, 2, 3], [4, 5, 6])
|
|
[1, 2, 3, 4, 5, 6]
|
|
```
|
|
|
|
### [`flat_map(enum, fun)`](`Enum.flat_map/2`)
|
|
|
|
```elixir
|
|
iex> Enum.flat_map(cart, fn item ->
|
|
...> List.duplicate(item.fruit, item.count)
|
|
...> end)
|
|
["apple", "apple", "apple", "banana", "orange",
|
|
"orange", "orange", "orange", "orange", "orange"]
|
|
```
|
|
|
|
### [`flat_map_reduce(enum, acc, fun)`](`Enum.flat_map_reduce/3`)
|
|
|
|
```elixir
|
|
iex> Enum.flat_map_reduce(cart, 0, fn item, acc ->
|
|
...> list = List.duplicate(item.fruit, item.count)
|
|
...> acc = acc + item.count
|
|
...> {list, acc}
|
|
...> end)
|
|
{["apple", "apple", "apple", "banana", "orange",
|
|
"orange", "orange", "orange", "orange", "orange"], 10}
|
|
```
|
|
|
|
### [`Comprehension`](`for/1`)
|
|
|
|
Flattening can also be done with comprehensions:
|
|
|
|
```elixir
|
|
iex> for item <- cart,
|
|
...> fruit <- List.duplicate(item.fruit, item.count) do
|
|
...> fruit
|
|
...> end
|
|
["apple", "apple", "apple", "banana", "orange",
|
|
"orange", "orange", "orange", "orange", "orange"]
|
|
```
|
|
|
|
## Conversion
|
|
{: .col-2}
|
|
|
|
### [`into(enum, collectable)`](`Enum.into/2`)
|
|
|
|
```elixir
|
|
iex> pairs = [{"apple", 3}, {"banana", 1}, {"orange", 6}]
|
|
iex> Enum.into(pairs, %{})
|
|
%{"apple" => 3, "banana" => 1, "orange" => 6}
|
|
```
|
|
|
|
### [`into(enum, collectable, transform)`](`Enum.into/3`)
|
|
|
|
```elixir
|
|
iex> Enum.into(cart, %{}, fn item ->
|
|
...> {item.fruit, item.count}
|
|
...> end)
|
|
%{"apple" => 3, "banana" => 1, "orange" => 6}
|
|
```
|
|
|
|
### [`to_list(enum)`](`Enum.to_list/1`)
|
|
|
|
```elixir
|
|
iex> Enum.to_list(1..5)
|
|
[1, 2, 3, 4, 5]
|
|
```
|
|
|
|
### [`Comprehension`](`for/1`)
|
|
|
|
Conversion can also be done with comprehensions:
|
|
|
|
```elixir
|
|
iex> for item <- cart, into: %{} do
|
|
...> {item.fruit, item.count}
|
|
...> end
|
|
%{"apple" => 3, "banana" => 1, "orange" => 6}
|
|
```
|
|
|
|
## Duplicates & uniques
|
|
{: .col-2}
|
|
|
|
### [`dedup(enum)`](`Enum.dedup/1`)
|
|
|
|
`dedup` only removes contiguous duplicates:
|
|
|
|
```elixir
|
|
iex> Enum.dedup([1, 2, 2, 3, 3, 3, 1, 2, 3])
|
|
[1, 2, 3, 1, 2, 3]
|
|
```
|
|
|
|
### [`dedup_by(enum, fun)`](`Enum.dedup_by/2`)
|
|
|
|
Remove contiguous entries given a property:
|
|
|
|
```elixir
|
|
iex> Enum.dedup_by(cart, & &1.fruit =~ "a")
|
|
[%{fruit: "apple", count: 3}]
|
|
iex> Enum.dedup_by(cart, & &1.count < 5)
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
### [`uniq(enum)`](`Enum.uniq/1`)
|
|
|
|
`uniq` applies to the whole collection:
|
|
|
|
```elixir
|
|
iex> Enum.uniq([1, 2, 2, 3, 3, 3, 1, 2, 3])
|
|
[1, 2, 3]
|
|
```
|
|
|
|
Comprehensions also support the `uniq: true` option.
|
|
|
|
### [`uniq_by(enum, fun)`](`Enum.uniq_by/2`)
|
|
|
|
Get entries which are unique by the last letter of the fruit:
|
|
|
|
```elixir
|
|
iex> Enum.uniq_by(cart, &String.last(&1.fruit))
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
]
|
|
```
|
|
|
|
## Indexing
|
|
{: .col-2}
|
|
|
|
### [`at(enum, index, default \\ nil)`](`Enum.at/2`)
|
|
|
|
```elixir
|
|
iex> Enum.at(cart, 0)
|
|
%{fruit: "apple", count: 3}
|
|
iex> Enum.at(cart, 10)
|
|
nil
|
|
iex> Enum.at(cart, 10, :none)
|
|
:none
|
|
```
|
|
|
|
Accessing a list by index in a loop is discouraged.
|
|
|
|
### [`fetch(enum, index)`](`Enum.fetch/2`)
|
|
|
|
```elixir
|
|
iex> Enum.fetch(cart, 0)
|
|
{:ok, %{fruit: "apple", count: 3}}
|
|
iex> Enum.fetch(cart, 10)
|
|
:error
|
|
```
|
|
|
|
### [`fetch!(enum, index)`](`Enum.fetch!/2`)
|
|
|
|
```elixir
|
|
iex> Enum.fetch!(cart, 0)
|
|
%{fruit: "apple", count: 3}
|
|
iex> Enum.fetch!(cart, 10)
|
|
** (Enum.OutOfBoundsError) out of bounds error
|
|
```
|
|
|
|
### [`with_index(enum)`](`Enum.with_index/1`)
|
|
|
|
```elixir
|
|
iex> Enum.with_index(cart)
|
|
[
|
|
{%{fruit: "apple", count: 3}, 0},
|
|
{%{fruit: "banana", count: 1}, 1},
|
|
{%{fruit: "orange", count: 6}, 2}
|
|
]
|
|
```
|
|
|
|
### [`with_index(enum, fun)`](`Enum.with_index/2`)
|
|
|
|
```elixir
|
|
iex> Enum.with_index(cart, fn item, index ->
|
|
...> {item.fruit, index}
|
|
...> end)
|
|
[
|
|
{"apple", 0},
|
|
{"banana", 1},
|
|
{"orange", 2}
|
|
]
|
|
```
|
|
|
|
## Finding
|
|
{: .col-2}
|
|
|
|
### [`find(enum, default \\ nil, fun)`](`Enum.find/2`)
|
|
|
|
```elixir
|
|
iex> Enum.find(cart, &(&1.fruit =~ "o"))
|
|
%{fruit: "orange", count: 6}
|
|
iex> Enum.find(cart, &(&1.fruit =~ "y"))
|
|
nil
|
|
iex> Enum.find(cart, :none, &(&1.fruit =~ "y"))
|
|
:none
|
|
```
|
|
|
|
### [`find_index(enum, fun)`](`Enum.find_index/2`)
|
|
|
|
```elixir
|
|
iex> Enum.find_index(cart, &(&1.fruit =~ "o"))
|
|
2
|
|
iex> Enum.find_index(cart, &(&1.fruit =~ "y"))
|
|
nil
|
|
```
|
|
|
|
### [`find_value(enum, default \\ nil, fun)`](`Enum.find_value/2`)
|
|
|
|
```elixir
|
|
iex> Enum.find_value(cart, fn item ->
|
|
...> if item.count == 1, do: item.fruit, else: nil
|
|
...> end)
|
|
"banana"
|
|
iex> Enum.find_value(cart, :none, fn item ->
|
|
...> if item.count == 100, do: item.fruit, else: nil
|
|
...> end)
|
|
:none
|
|
```
|
|
|
|
## Grouping
|
|
{: .col-2}
|
|
|
|
### [`group_by(enum, key_fun)`](`Enum.group_by/2`)
|
|
|
|
Group by the last letter of the fruit:
|
|
|
|
```elixir
|
|
iex> Enum.group_by(cart, &String.last(&1.fruit))
|
|
%{
|
|
"a" => [%{fruit: "banana", count: 1}],
|
|
"e" => [
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
}
|
|
```
|
|
|
|
### [`group_by(enum, key_fun, value_fun)`](`Enum.group_by/3`)
|
|
|
|
Group by the last letter of the fruit with custom value:
|
|
|
|
```elixir
|
|
iex> Enum.group_by(cart, &String.last(&1.fruit), & &1.fruit)
|
|
%{
|
|
"a" => ["banana"],
|
|
"e" => ["apple", "orange"]
|
|
}
|
|
```
|
|
|
|
## Joining & interspersing
|
|
{: .col-2}
|
|
|
|
### [`join(enum, joiner \\ "")`](`Enum.join/2`)
|
|
|
|
```elixir
|
|
iex> Enum.join(["apple", "banana", "orange"], ", ")
|
|
"apple, banana, orange"
|
|
```
|
|
|
|
### [`map_join(enum, joiner \\ "", mapper)`](`Enum.map_join/3`)
|
|
|
|
```elixir
|
|
iex> Enum.map_join(cart, ", ", & &1.fruit)
|
|
"apple, banana, orange"
|
|
```
|
|
|
|
### [`intersperse(enum, separator \\ "")`](`Enum.intersperse/2`)
|
|
|
|
```elixir
|
|
iex> Enum.intersperse(["apple", "banana", "orange"], ", ")
|
|
["apple", ", ", "banana", ", ", "orange"]
|
|
```
|
|
|
|
### [`map_intersperse(enum, separator \\ "", mapper)`](`Enum.map_intersperse/3`)
|
|
|
|
```elixir
|
|
iex> Enum.map_intersperse(cart, ", ", & &1.fruit)
|
|
["apple", ", ", "banana", ", ", "orange"]
|
|
```
|
|
|
|
## Slicing
|
|
{: .col-2}
|
|
|
|
### [`slice(enum, index_range)`](`Enum.slice/2`)
|
|
|
|
```elixir
|
|
iex> Enum.slice(cart, 0..1)
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
]
|
|
```
|
|
|
|
Negative ranges count from the back:
|
|
|
|
```elixir
|
|
iex> Enum.slice(cart, -2..-1)
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
### [`slice(enum, start_index, amount)`](`Enum.slice/3`)
|
|
|
|
```elixir
|
|
iex> Enum.slice(cart, 1, 2)
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
### [`slide(enum, range_or_single_index, insertion_index)`](`Enum.slide/3`)
|
|
|
|
```elixir
|
|
fruits = ["apple", "banana", "grape", "orange", "pear"]
|
|
iex> Enum.slide(fruits, 2, 0)
|
|
["grape", "apple", "banana", "orange", "pear"]
|
|
iex> Enum.slide(fruits, 2, 4)
|
|
["apple", "banana", "orange", "pear", "grape"]
|
|
iex> Enum.slide(fruits, 1..3, 0)
|
|
["banana", "grape", "orange", "apple", "pear"]
|
|
iex> Enum.slide(fruits, 1..3, 4)
|
|
["apple", "pear", "banana", "grape", "orange"]
|
|
```
|
|
|
|
## Reversing
|
|
{: .col-2}
|
|
|
|
### [`reverse(enum)`](`Enum.reverse/1`)
|
|
|
|
```elixir
|
|
iex> Enum.reverse(cart)
|
|
[
|
|
%{fruit: "orange", count: 6},
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "apple", count: 3}
|
|
]
|
|
```
|
|
|
|
### [`reverse(enum, tail)`](`Enum.reverse/2`)
|
|
|
|
```elixir
|
|
iex> Enum.reverse(cart, [:this_will_be, :the_tail])
|
|
[
|
|
%{fruit: "orange", count: 6},
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "apple", count: 3},
|
|
:this_will_be,
|
|
:the_tail
|
|
]
|
|
```
|
|
|
|
### [`reverse_slice(enum, start_index, count)`](`Enum.reverse_slice/3`)
|
|
|
|
```elixir
|
|
iex> Enum.reverse_slice(cart, 1, 2)
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6},
|
|
%{fruit: "banana", count: 1}
|
|
]
|
|
```
|
|
|
|
## Splitting
|
|
{: .col-2}
|
|
|
|
### [`split(enum, amount)`](`Enum.split/2`)
|
|
|
|
```elixir
|
|
iex> Enum.split(cart, 1)
|
|
{[%{fruit: "apple", count: 3}],
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]}
|
|
```
|
|
|
|
Negative indexes count from the back:
|
|
|
|
```elixir
|
|
iex> Enum.split(cart, -1)
|
|
{[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
],
|
|
[%{fruit: "orange", count: 6}]}
|
|
```
|
|
|
|
### [`split_while(enum, fun)`](`Enum.split_while/2`)
|
|
|
|
Stops splitting as soon as it is false:
|
|
|
|
```elixir
|
|
iex> Enum.split_while(cart, &(&1.fruit =~ "e"))
|
|
{[%{fruit: "apple", count: 3}],
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]}
|
|
```
|
|
|
|
### [`split_with(enum, fun)`](`Enum.split_with/2`)
|
|
|
|
Splits the whole collection:
|
|
|
|
```elixir
|
|
iex> Enum.split_with(cart, &(&1.fruit =~ "e"))
|
|
{[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6}
|
|
],
|
|
[%{fruit: "banana", count: 1}]}
|
|
```
|
|
|
|
## Splitting (drop and take)
|
|
{: .col-2}
|
|
|
|
### [`drop(enum, amount)`](`Enum.drop/2`)
|
|
|
|
```elixir
|
|
iex> Enum.drop(cart, 1)
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
Negative indexes count from the back:
|
|
|
|
```elixir
|
|
iex> Enum.drop(cart, -1)
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
]
|
|
```
|
|
|
|
### [`drop_every(enum, nth)`](`Enum.drop_every/2`)
|
|
|
|
```elixir
|
|
iex> Enum.drop_every(cart, 2)
|
|
[%{fruit: "banana", count: 1}]
|
|
```
|
|
|
|
### [`drop_while(enum, fun)`](`Enum.drop_while/2`)
|
|
|
|
```elixir
|
|
iex> Enum.drop_while(cart, &(&1.fruit =~ "e"))
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
### [`take(enum, amount)`](`Enum.take/2`)
|
|
|
|
```elixir
|
|
iex> Enum.take(cart, 1)
|
|
[%{fruit: "apple", count: 3}]
|
|
```
|
|
|
|
Negative indexes count from the back:
|
|
|
|
```elixir
|
|
iex> Enum.take(cart, -1)
|
|
[%{fruit: "orange", count: 6}]
|
|
```
|
|
|
|
### [`take_every(enum, nth)`](`Enum.take_every/2`)
|
|
|
|
```elixir
|
|
iex> Enum.take_every(cart, 2)
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
### [`take_while(enum, fun)`](`Enum.take_while/2`)
|
|
|
|
```elixir
|
|
iex> Enum.take_while(cart, &(&1.fruit =~ "e"))
|
|
[%{fruit: "apple", count: 3}]
|
|
```
|
|
|
|
## Random
|
|
{: .col-2}
|
|
|
|
### [`random(enum)`](`Enum.random/1`)
|
|
|
|
Results will vary on every call:
|
|
|
|
```elixir
|
|
iex> Enum.random(cart)
|
|
%{fruit: "orange", count: 6}
|
|
```
|
|
|
|
### [`take_random(enum, count)`](`Enum.take_random/2`)
|
|
|
|
Results will vary on every call:
|
|
|
|
```elixir
|
|
iex> Enum.take_random(cart, 2)
|
|
[
|
|
%{fruit: "orange", count: 6},
|
|
%{fruit: "apple", count: 3}
|
|
]
|
|
```
|
|
|
|
### [`shuffle(enum)`](`Enum.shuffle/1`)
|
|
|
|
Results will vary on every call:
|
|
|
|
```elixir
|
|
iex> Enum.shuffle(cart)
|
|
[
|
|
%{fruit: "orange", count: 6},
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
]
|
|
```
|
|
|
|
## Chunking
|
|
{: .col-2}
|
|
|
|
### [`chunk_by(enum, fun)`](`Enum.chunk_by/2`)
|
|
|
|
```elixir
|
|
iex> Enum.chunk_by(cart, &String.length(&1.fruit))
|
|
[
|
|
[%{fruit: "apple", count: 3}],
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
]
|
|
```
|
|
|
|
### [`chunk_every(enum, count)`](`Enum.chunk_every/2`)
|
|
|
|
```elixir
|
|
iex> Enum.chunk_every(cart, 2)
|
|
[
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
],
|
|
[%{fruit: "orange", count: 6}]
|
|
]
|
|
```
|
|
|
|
### [`chunk_every(enum, count, step, leftover \\ [])`](`Enum.chunk_every/2`)
|
|
|
|
```elixir
|
|
iex> Enum.chunk_every(cart, 2, 2, [:elements, :to_complete])
|
|
[
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
],
|
|
[
|
|
%{fruit: "orange", count: 6},
|
|
:elements
|
|
]
|
|
]
|
|
iex> Enum.chunk_every(cart, 2, 1, :discard)
|
|
[
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1}
|
|
],
|
|
[
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
]
|
|
```
|
|
|
|
See `Enum.chunk_while/4` for custom chunking.
|
|
|
|
## Zipping
|
|
{: .col-2}
|
|
|
|
### [`zip(enum1, enum2)`](`Enum.zip/2`)
|
|
|
|
```elixir
|
|
iex> fruits = ["apple", "banana", "orange"]
|
|
iex> counts = [3, 1, 6]
|
|
iex> Enum.zip(fruits, counts)
|
|
[{"apple", 3}, {"banana", 1}, {"orange", 6}]
|
|
```
|
|
|
|
See `Enum.zip/1` for zipping many collections at once.
|
|
|
|
### [`zip_with(enum1, enum2, fun)`](`Enum.zip_with/2`)
|
|
|
|
```elixir
|
|
iex> fruits = ["apple", "banana", "orange"]
|
|
iex> counts = [3, 1, 6]
|
|
iex> Enum.zip_with(fruits, counts, fn fruit, count ->
|
|
...> %{fruit: fruit, count: count}
|
|
...> end)
|
|
[
|
|
%{fruit: "apple", count: 3},
|
|
%{fruit: "banana", count: 1},
|
|
%{fruit: "orange", count: 6}
|
|
]
|
|
```
|
|
|
|
See `Enum.zip_with/2` for zipping many collections at once.
|
|
|
|
### [`zip_reduce(left, right, acc, fun)`](`Enum.zip_reduce/4`)
|
|
|
|
```elixir
|
|
iex> fruits = ["apple", "banana", "orange"]
|
|
iex> counts = [3, 1, 6]
|
|
iex> Enum.zip_reduce(fruits, counts, 0, fn fruit, count, acc ->
|
|
...> price = if fruit =~ "e", do: count * 2, else: count
|
|
...> acc + price
|
|
...> end)
|
|
19
|
|
```
|
|
|
|
See `Enum.zip_reduce/3` for zipping many collections at once.
|
|
|
|
### [`unzip(list)`](`Enum.unzip/1`)
|
|
|
|
```elixir
|
|
iex> cart |> Enum.map(&{&1.fruit, &1.count}) |> Enum.unzip()
|
|
{["apple", "banana", "orange"], [3, 1, 6]}
|
|
```
|