View Source Enum (Elixir v1.11.1)

Provides a set of algorithms to work with enumerables.

In Elixir, an enumerable is any data type that implements the Enumerable protocol. Lists ([1, 2, 3]), Maps (%{foo: 1, bar: 2}) and Ranges (1..3) are common data types used as enumerables:

iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
[2, 4, 6]

iex> Enum.sum([1, 2, 3])
6

iex> Enum.map(1..3, fn x -> x * 2 end)
[2, 4, 6]

iex> Enum.sum(1..3)
6

iex> map = %{"a" => 1, "b" => 2}
iex> Enum.map(map, fn {k, v} -> {k, v * 2} end)
[{"a", 2}, {"b", 4}]

However, many other enumerables exist in the language, such as MapSets and the data type returned by File.stream!/3 which allows a file to be traversed as if it was an enumerable.

The functions in this module work in linear time. This means that, the time it takes to perform an operation grows at the same rate as the length of the enumerable. This is expected on operations such as Enum.map/2. After all, if we want to traverse every element on a list, the longer the list, the more elements we need to traverse, and the longer it will take.

This linear behaviour should also be expected on operations like count/1, member?/2, at/2 and similar. While Elixir does allow data types to provide performant variants for such operations, you should not expect it to always be available, since the Enum module is meant to work with a large variety of data types and not all data types can provide optimized behaviour.

Finally, note the functions in the Enum module are eager: they will traverse the enumerable as soon as they are invoked. This is particularly dangerous when working with infinite enumerables. In such cases, you should use the Stream module, which allows you to lazily express computations, without traversing collections, and work with possibly infinite collections. See the Stream module for examples and documentation.

Link to this section Summary

Types

Zero-based index. It can also be a negative integer.

t()

Functions

Returns true if fun.(element) is truthy for all elements in enumerable.

Returns true if fun.(element) is truthy for at least one element in enumerable.

Finds the element at the given index (zero-based).

Splits enumerable on every element for which fun returns a new value.

Shortcut to chunk_every(enumerable, count, count).

Returns list of lists containing count elements each, where each new chunk starts step elements into the enumerable.

Chunks the enumerable with fine grained control when every chunk is emitted.

Given an enumerable of enumerables, concatenates the enumerables into a single list.

Concatenates the enumerable on the right with the enumerable on the left.

Returns the size of the enumerable.

Returns the count of elements in the enumerable for which fun returns a truthy value.

Enumerates the enumerable, returning a list where all consecutive duplicated elements are collapsed to a single element.

Enumerates the enumerable, returning a list where all consecutive duplicated elements are collapsed to a single element.

Drops the amount of elements from the enumerable.

Returns a list of every nth element in the enumerable dropped, starting with the first element.

Drops elements at the beginning of the enumerable while fun returns a truthy value.

Invokes the given fun for each element in the enumerable.

Determines if the enumerable is empty.

Finds the element at the given index (zero-based).

Finds the element at the given index (zero-based).

Filters the enumerable, i.e. returns only those elements for which fun returns a truthy value.

Returns the first element for which fun returns a truthy value. If no such element is found, returns default.

Similar to find/3, but returns the index (zero-based) of the element instead of the element itself.

Similar to find/3, but returns the value of the function invocation instead of the element itself.

Maps the given fun over enumerable and flattens the result.

Maps and reduces an enumerable, flattening the given results (only one level deep).

Returns a map with keys as unique elements of enumerable and values as the count of every element.

Returns a map with keys as unique elements given by key_fun and values as the count of every element.

Splits the enumerable into groups based on key_fun.

Intersperses element between each element of the enumeration.

Inserts the given enumerable into a collectable.

Inserts the given enumerable into a collectable according to the transformation function.

Joins the given enumerable into a string using joiner as a separator.

Returns a list where each element is the result of invoking fun on each corresponding element of enumerable.

Returns a list of results of invoking fun on every nth element of enumerable, starting with the first element.

Maps and intersperses the given enumerable in one pass.

Maps and joins the given enumerable in one pass.

Invokes the given function to each element in the enumerable to reduce it to a single element, while keeping an accumulator.

Returns the maximal element in the enumerable according to Erlang's term ordering.

Returns the maximal element in the enumerable as calculated by the given fun.

Checks if element exists within the enumerable.

Returns the minimal element in the enumerable according to Erlang's term ordering.

Returns the minimal element in the enumerable as calculated by the given fun.

Returns a tuple with the minimal and the maximal elements in the enumerable according to Erlang's term ordering.

Returns a tuple with the minimal and the maximal elements in the enumerable as calculated by the given function.

Returns a random element of an enumerable.

Invokes fun for each element in the enumerable with the accumulator.

Invokes fun for each element in the enumerable with the accumulator.

Reduces enumerable until fun returns {:halt, term}.

Returns a list of elements in enumerable excluding those for which the function fun returns a truthy value.

Returns a list of elements in enumerable in reverse order.

Reverses the elements in enumerable, appends the tail, and returns it as a list.

Reverses the enumerable in the range from initial start_index through count elements.

Applies the given function to each element in the enumerable, storing the result in a list and passing it as the accumulator for the next computation. Uses the first element in the enumerable as the starting value.

Applies the given function to each element in the enumerable, storing the result in a list and passing it as the accumulator for the next computation. Uses the given acc as the starting value.

Returns a list with the elements of enumerable shuffled.

Returns a subset list of the given enumerable by index_range.

Returns a subset list of the given enumerable, from start_index (zero-based) with amount number of elements if available.

Sorts the enumerable according to Erlang's term ordering.

Sorts the enumerable by the given function.

Sorts the mapped results of the enumerable according to the provided sorter function.

Splits the enumerable into two enumerables, leaving count elements in the first one.

Splits enumerable in two at the position of the element for which fun returns a falsy value (false or nil) for the first time.

Splits the enumerable in two lists according to the given function fun.

Returns the sum of all elements.

Takes an amount of elements from the beginning or the end of the enumerable.

Returns a list of every nth element in the enumerable, starting with the first element.

Takes count random elements from enumerable.

Takes the elements from the beginning of the enumerable while fun returns a truthy value.

Converts enumerable to a list.

Enumerates the enumerable, removing all duplicated elements.

Enumerates the enumerable, by removing the elements for which function fun returned duplicate elements.

Opposite of zip/2. Extracts two-element tuples from the given enumerable and groups them together.

Returns the enumerable with each element wrapped in a tuple alongside its index.

Zips corresponding elements from a finite collection of enumerables into one list of tuples.

Zips corresponding elements from two enumerables into one list of tuples.

Link to this section Types

@type acc() :: any()
@type default() :: any()
@type element() :: any()
@type index() :: integer()

Zero-based index. It can also be a negative integer.

@type t() :: Enumerable.t()

Link to this section Functions

Link to this function

all?(enumerable, fun \\ fn x -> x end)

View Source
@spec all?(t(), (element() -> as_boolean(term()))) :: boolean()

Returns true if fun.(element) is truthy for all elements in enumerable.

Iterates over the enumerable and invokes fun on each element. When an invocation of fun returns a falsy value (false or nil) iteration stops immediately and false is returned. In all other cases true is returned.

Examples

iex> Enum.all?([2, 4, 6], fn x -> rem(x, 2) == 0 end)
true

iex> Enum.all?([2, 3, 4], fn x -> rem(x, 2) == 0 end)
false

iex> Enum.all?([], fn x -> x > 0 end)
true

If no function is given, the truthiness of each element is checked during iteration. When an element has a falsy value (false or nil) iteration stops immediately and false is returned. In all other cases true is returned.

iex> Enum.all?([1, 2, 3])
true

iex> Enum.all?([1, nil, 3])
false

iex> Enum.all?([])
true
Link to this function

any?(enumerable, fun \\ fn x -> x end)

View Source
@spec any?(t(), (element() -> as_boolean(term()))) :: boolean()

Returns true if fun.(element) is truthy for at least one element in enumerable.

Iterates over the enumerable and invokes fun on each element. When an invocation of fun returns a truthy value (neither false nor nil) iteration stops immediately and true is returned. In all other cases false is returned.

Examples

iex> Enum.any?([2, 4, 6], fn x -> rem(x, 2) == 1 end)
false

iex> Enum.any?([2, 3, 4], fn x -> rem(x, 2) == 1 end)
true

iex> Enum.any?([], fn x -> x > 0 end)
false

If no function is given, the truthiness of each element is checked during iteration. When an element has a truthy value (neither false nor nil) iteration stops immediately and true is returned. In all other cases false is returned.

iex> Enum.any?([false, false, false])
false

iex> Enum.any?([false, true, false])
true

iex> Enum.any?([])
false
Link to this function

at(enumerable, index, default \\ nil)

View Source
@spec at(t(), index(), default()) :: element() | default()

Finds the element at the given index (zero-based).

Returns default if index is out of bounds.

A negative index can be passed, which means the enumerable is enumerated once and the index is counted from the end (for example, -1 finds the last element).

Examples

iex> Enum.at([2, 4, 6], 0)
2

iex> Enum.at([2, 4, 6], 2)
6

iex> Enum.at([2, 4, 6], 4)
nil

iex> Enum.at([2, 4, 6], 4, :none)
:none
Link to this function

chunk_by(enumerable, fun)

View Source
@spec chunk_by(t(), (element() -> any())) :: [list()]

Splits enumerable on every element for which fun returns a new value.

Returns a list of lists.

Examples

iex> Enum.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1))
[[1], [2, 2], [3], [4, 4, 6], [7, 7]]
Link to this function

chunk_every(enumerable, count)

View Source (since 1.5.0)
@spec chunk_every(t(), pos_integer()) :: [list()]

Shortcut to chunk_every(enumerable, count, count).

Link to this function

chunk_every(enumerable, count, step, leftover \\ [])

View Source (since 1.5.0)
@spec chunk_every(t(), pos_integer(), pos_integer(), t() | :discard) :: [list()]

Returns list of lists containing count elements each, where each new chunk starts step elements into the enumerable.

step is optional and, if not passed, defaults to count, i.e. chunks do not overlap.

If the last chunk does not have count elements to fill the chunk, elements are taken from leftover to fill in the chunk. If leftover does not have enough elements to fill the chunk, then a partial chunk is returned with less than count elements.

If :discard is given in leftover, the last chunk is discarded unless it has exactly count elements.

Examples

iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 2)
[[1, 2], [3, 4], [5, 6]]

iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard)
[[1, 2, 3], [3, 4, 5]]

iex> Enum.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7])
[[1, 2, 3], [3, 4, 5], [5, 6, 7]]

iex> Enum.chunk_every([1, 2, 3, 4], 3, 3, [])
[[1, 2, 3], [4]]

iex> Enum.chunk_every([1, 2, 3, 4], 10)
[[1, 2, 3, 4]]

iex> Enum.chunk_every([1, 2, 3, 4, 5], 2, 3, [])
[[1, 2], [4, 5]]
Link to this function

chunk_while(enumerable, acc, chunk_fun, after_fun)

View Source (since 1.5.0)
@spec chunk_while(
  t(),
  acc(),
  (element(), acc() -> {:cont, chunk, acc()} | {:cont, acc()} | {:halt, acc()}),
  (acc() -> {:cont, chunk, acc()} | {:cont, acc()})
) :: Enumerable.t()
when chunk: any()

Chunks the enumerable with fine grained control when every chunk is emitted.

chunk_fun receives the current element and the accumulator and must return {:cont, chunk, acc} to emit the given chunk and continue with accumulator or {:cont, acc} to not emit any chunk and continue with the return accumulator.

after_fun is invoked when iteration is done and must also return {:cont, chunk, acc} or {:cont, acc}.

Returns a list of lists.

Examples

iex> chunk_fun = fn element, acc ->
...>   if rem(element, 2) == 0 do
...>     {:cont, Enum.reverse([element | acc]), []}
...>   else
...>     {:cont, [element | acc]}
...>   end
...> end
iex> after_fun = fn
...>   [] -> {:cont, []}
...>   acc -> {:cont, Enum.reverse(acc), []}
...> end
iex> Enum.chunk_while(1..10, [], chunk_fun, after_fun)
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
@spec concat(t()) :: t()

Given an enumerable of enumerables, concatenates the enumerables into a single list.

Examples

iex> Enum.concat([1..3, 4..6, 7..9])
[1, 2, 3, 4, 5, 6, 7, 8, 9]

iex> Enum.concat([[1, [2], 3], [4], [5, 6]])
[1, [2], 3, 4, 5, 6]
@spec concat(t(), t()) :: t()

Concatenates the enumerable on the right with the enumerable on the left.

This function produces the same result as the Kernel.++/2 operator for lists.

Examples

iex> Enum.concat(1..3, 4..6)
[1, 2, 3, 4, 5, 6]

iex> Enum.concat([1, 2, 3], [4, 5, 6])
[1, 2, 3, 4, 5, 6]
@spec count(t()) :: non_neg_integer()

Returns the size of the enumerable.

Examples

iex> Enum.count([1, 2, 3])
3
@spec count(t(), (element() -> as_boolean(term()))) :: non_neg_integer()

Returns the count of elements in the enumerable for which fun returns a truthy value.

Examples

iex> Enum.count([1, 2, 3, 4, 5], fn x -> rem(x, 2) == 0 end)
2
@spec dedup(t()) :: list()

Enumerates the enumerable, returning a list where all consecutive duplicated elements are collapsed to a single element.

Elements are compared using ===/2.

If you want to remove all duplicated elements, regardless of order, see uniq/1.

Examples

iex> Enum.dedup([1, 2, 3, 3, 2, 1])
[1, 2, 3, 2, 1]

iex> Enum.dedup([1, 1, 2, 2.0, :three, :three])
[1, 2, 2.0, :three]
Link to this function

dedup_by(enumerable, fun)

View Source
@spec dedup_by(t(), (element() -> term())) :: list()

Enumerates the enumerable, returning a list where all consecutive duplicated elements are collapsed to a single element.

The function fun maps every element to a term which is used to determine if two elements are duplicates.

Examples

iex> Enum.dedup_by([{1, :a}, {2, :b}, {2, :c}, {1, :a}], fn {x, _} -> x end)
[{1, :a}, {2, :b}, {1, :a}]

iex> Enum.dedup_by([5, 1, 2, 3, 2, 1], fn x -> x > 2 end)
[5, 1, 3, 2]
Link to this function

drop(enumerable, amount)

View Source
@spec drop(t(), integer()) :: list()

Drops the amount of elements from the enumerable.

If a negative amount is given, the amount of last values will be dropped. The enumerable will be enumerated once to retrieve the proper index and the remaining calculation is performed from the end.

Examples

iex> Enum.drop([1, 2, 3], 2)
[3]

iex> Enum.drop([1, 2, 3], 10)
[]

iex> Enum.drop([1, 2, 3], 0)
[1, 2, 3]

iex> Enum.drop([1, 2, 3], -1)
[1, 2]
Link to this function

drop_every(enumerable, nth)

View Source
@spec drop_every(t(), non_neg_integer()) :: list()

Returns a list of every nth element in the enumerable dropped, starting with the first element.

The first element is always dropped, unless nth is 0.

The second argument specifying every nth element must be a non-negative integer.

Examples

iex> Enum.drop_every(1..10, 2)
[2, 4, 6, 8, 10]

iex> Enum.drop_every(1..10, 0)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

iex> Enum.drop_every([1, 2, 3], 1)
[]
Link to this function

drop_while(enumerable, fun)

View Source
@spec drop_while(t(), (element() -> as_boolean(term()))) :: list()

Drops elements at the beginning of the enumerable while fun returns a truthy value.

Examples

iex> Enum.drop_while([1, 2, 3, 2, 1], fn x -> x < 3 end)
[3, 2, 1]
@spec each(t(), (element() -> any())) :: :ok

Invokes the given fun for each element in the enumerable.

Returns :ok.

Examples

Enum.each(["some", "example"], fn x -> IO.puts(x) end)
"some"
"example"
#=> :ok
@spec empty?(t()) :: boolean()

Determines if the enumerable is empty.

Returns true if enumerable is empty, otherwise false.

Examples

iex> Enum.empty?([])
true

iex> Enum.empty?([1, 2, 3])
false
Link to this function

fetch(enumerable, index)

View Source
@spec fetch(t(), index()) :: {:ok, element()} | :error

Finds the element at the given index (zero-based).

Returns {:ok, element} if found, otherwise :error.

A negative index can be passed, which means the enumerable is enumerated once and the index is counted from the end (for example, -1 fetches the last element).

Examples

iex> Enum.fetch([2, 4, 6], 0)
{:ok, 2}

iex> Enum.fetch([2, 4, 6], -3)
{:ok, 2}

iex> Enum.fetch([2, 4, 6], 2)
{:ok, 6}

iex> Enum.fetch([2, 4, 6], 4)
:error
Link to this function

fetch!(enumerable, index)

View Source
@spec fetch!(t(), index()) :: element()

Finds the element at the given index (zero-based).

Raises OutOfBoundsError if the given index is outside the range of the enumerable.

Examples

iex> Enum.fetch!([2, 4, 6], 0)
2

iex> Enum.fetch!([2, 4, 6], 2)
6

iex> Enum.fetch!([2, 4, 6], 4)
** (Enum.OutOfBoundsError) out of bounds error
@spec filter(t(), (element() -> as_boolean(term()))) :: list()

Filters the enumerable, i.e. returns only those elements for which fun returns a truthy value.

See also reject/2 which discards all elements where the function returns a truthy value.

Examples

iex> Enum.filter([1, 2, 3], fn x -> rem(x, 2) == 0 end)
[2]

Keep in mind that filter is not capable of filtering and transforming an element at the same time. If you would like to do so, consider using flat_map/2. For example, if you want to convert all strings that represent an integer and discard the invalid one in one pass:

strings = ["1234", "abc", "12ab"]

Enum.flat_map(strings, fn string ->
  case Integer.parse(string) do
    # transform to integer
    {int, _rest} -> [int]
    # skip the value
    :error -> []
  end
end)
Link to this function

find(enumerable, default \\ nil, fun)

View Source
@spec find(t(), default(), (element() -> any())) :: element() | default()

Returns the first element for which fun returns a truthy value. If no such element is found, returns default.

Examples

iex> Enum.find([2, 3, 4], fn x -> rem(x, 2) == 1 end)
3

iex> Enum.find([2, 4, 6], fn x -> rem(x, 2) == 1 end)
nil
iex> Enum.find([2, 4, 6], 0, fn x -> rem(x, 2) == 1 end)
0
Link to this function

find_index(enumerable, fun)

View Source
@spec find_index(t(), (element() -> any())) :: non_neg_integer() | nil

Similar to find/3, but returns the index (zero-based) of the element instead of the element itself.

Examples

iex> Enum.find_index([2, 4, 6], fn x -> rem(x, 2) == 1 end)
nil

iex> Enum.find_index([2, 3, 4], fn x -> rem(x, 2) == 1 end)
1
Link to this function

find_value(enumerable, default \\ nil, fun)

View Source
@spec find_value(t(), any(), (element() -> any())) :: any() | nil

Similar to find/3, but returns the value of the function invocation instead of the element itself.

The return value is considered to be found when the result is truthy (neither nil nor false).

Examples

iex> Enum.find_value([2, 3, 4], fn x ->
...>   if x > 2, do: x * x
...> end)
9

iex> Enum.find_value([2, 4, 6], fn x -> rem(x, 2) == 1 end)
nil

iex> Enum.find_value([2, 3, 4], fn x -> rem(x, 2) == 1 end)
true

iex> Enum.find_value([1, 2, 3], "no bools!", &is_boolean/1)
"no bools!"
Link to this function

flat_map(enumerable, fun)

View Source
@spec flat_map(t(), (element() -> t())) :: list()

Maps the given fun over enumerable and flattens the result.

This function returns a new enumerable built by appending the result of invoking fun on each element of enumerable together; conceptually, this is similar to a combination of map/2 and concat/1.

Examples

iex> Enum.flat_map([:a, :b, :c], fn x -> [x, x] end)
[:a, :a, :b, :b, :c, :c]

iex> Enum.flat_map([{1, 3}, {4, 6}], fn {x, y} -> x..y end)
[1, 2, 3, 4, 5, 6]

iex> Enum.flat_map([:a, :b, :c], fn x -> [[x]] end)
[[:a], [:b], [:c]]
Link to this function

flat_map_reduce(enumerable, acc, fun)

View Source
@spec flat_map_reduce(t(), acc(), fun) :: {[any()], acc()}
when fun: (element(), acc() -> {t(), acc()} | {:halt, acc()})

Maps and reduces an enumerable, flattening the given results (only one level deep).

It expects an accumulator and a function that receives each enumerable element, and must return a tuple containing a new enumerable (often a list) with the new accumulator or a tuple with :halt as first element and the accumulator as second.

Examples

iex> enumerable = 1..100
iex> n = 3
iex> Enum.flat_map_reduce(enumerable, 0, fn x, acc ->
...>   if acc < n, do: {[x], acc + 1}, else: {:halt, acc}
...> end)
{[1, 2, 3], 3}

iex> Enum.flat_map_reduce(1..5, 0, fn x, acc -> {[[x]], acc + x} end)
{[[1], [2], [3], [4], [5]], 15}
Link to this function

frequencies(enumerable)

View Source (since 1.10.0)
@spec frequencies(t()) :: map()

Returns a map with keys as unique elements of enumerable and values as the count of every element.

Examples

iex> Enum.frequencies(~w{ant buffalo ant ant buffalo dingo})
%{"ant" => 3, "buffalo" => 2, "dingo" => 1}
Link to this function

frequencies_by(enumerable, key_fun)

View Source (since 1.10.0)
@spec frequencies_by(t(), (element() -> any())) :: map()

Returns a map with keys as unique elements given by key_fun and values as the count of every element.

Examples

iex> Enum.frequencies_by(~w{aa aA bb cc}, &String.downcase/1)
%{"aa" => 2, "bb" => 1, "cc" => 1}

iex> Enum.frequencies_by(~w{aaa aA bbb cc c}, &String.length/1)
%{3 => 2, 2 => 2, 1 => 1}
Link to this function

group_by(enumerable, key_fun, value_fun \\ fn x -> x end)

View Source
@spec group_by(t(), (element() -> any()), (element() -> any())) :: map()

Splits the enumerable into groups based on key_fun.

The result is a map where each key is given by key_fun and each value is a list of elements given by value_fun. The order of elements within each list is preserved from the enumerable. However, like all maps, the resulting map is unordered.

Examples

iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1)
%{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}

iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1)
%{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]}
Link to this function

intersperse(enumerable, element)

View Source
@spec intersperse(t(), element()) :: list()

Intersperses element between each element of the enumeration.

Examples

iex> Enum.intersperse([1, 2, 3], 0)
[1, 0, 2, 0, 3]

iex> Enum.intersperse([1], 0)
[1]

iex> Enum.intersperse([], 0)
[]
Link to this function

into(enumerable, collectable)

View Source
@spec into(Enumerable.t(), Collectable.t()) :: Collectable.t()

Inserts the given enumerable into a collectable.

Note that passing a non-empty list as the collectable is deprecated. If you're collecting into a non-empty keyword list, consider using Keyword.merge/2. If you're collecting into a non-empty list, consider something like to_list(enumerable) ++ collectable.

Examples

iex> Enum.into([1, 2], [])
[1, 2]

iex> Enum.into([a: 1, b: 2], %{})
%{a: 1, b: 2}

iex> Enum.into(%{a: 1}, %{b: 2})
%{a: 1, b: 2}

iex> Enum.into([a: 1, a: 2], %{})
%{a: 2}
Link to this function

into(enumerable, collectable, transform)

View Source
@spec into(Enumerable.t(), Collectable.t(), (term() -> term())) :: Collectable.t()

Inserts the given enumerable into a collectable according to the transformation function.

Examples

iex> Enum.into([2, 3], [3], fn x -> x * 3 end)
[3, 6, 9]

iex> Enum.into(%{a: 1, b: 2}, %{c: 3}, fn {k, v} -> {k, v * 2} end)
%{a: 2, b: 4, c: 3}
Link to this function

join(enumerable, joiner \\ "")

View Source
@spec join(t(), String.t()) :: String.t()

Joins the given enumerable into a string using joiner as a separator.

If joiner is not passed at all, it defaults to an empty string.

All elements in the enumerable must be convertible to a string, otherwise an error is raised.

Examples

iex> Enum.join([1, 2, 3])
"123"

iex> Enum.join([1, 2, 3], " = ")
"1 = 2 = 3"
@spec map(t(), (element() -> any())) :: list()

Returns a list where each element is the result of invoking fun on each corresponding element of enumerable.

For maps, the function expects a key-value tuple.

Examples

iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
[2, 4, 6]

iex> Enum.map([a: 1, b: 2], fn {k, v} -> {k, -v} end)
[a: -1, b: -2]
Link to this function

map_every(enumerable, nth, fun)

View Source (since 1.4.0)
@spec map_every(t(), non_neg_integer(), (element() -> any())) :: list()

Returns a list of results of invoking fun on every nth element of enumerable, starting with the first element.

The first element is always passed to the given function, unless nth is 0.

The second argument specifying every nth element must be a non-negative integer.

If nth is 0, then enumerable is directly converted to a list, without fun being ever applied.

Examples

iex> Enum.map_every(1..10, 2, fn x -> x + 1000 end)
[1001, 2, 1003, 4, 1005, 6, 1007, 8, 1009, 10]

iex> Enum.map_every(1..10, 3, fn x -> x + 1000 end)
[1001, 2, 3, 1004, 5, 6, 1007, 8, 9, 1010]

iex> Enum.map_every(1..5, 0, fn x -> x + 1000 end)
[1, 2, 3, 4, 5]

iex> Enum.map_every([1, 2, 3], 1, fn x -> x + 1000 end)
[1001, 1002, 1003]
Link to this function

map_intersperse(enumerable, separator, mapper)

View Source (since 1.10.0)
@spec map_intersperse(t(), element(), (element() -> any())) :: list()

Maps and intersperses the given enumerable in one pass.

Examples

iex> Enum.map_intersperse([1, 2, 3], :a, &(&1 * 2))
[2, :a, 4, :a, 6]
Link to this function

map_join(enumerable, joiner \\ "", mapper)

View Source
@spec map_join(t(), String.t(), (element() -> String.Chars.t())) :: String.t()

Maps and joins the given enumerable in one pass.

If joiner is not passed at all, it defaults to an empty string.

All elements returned from invoking the mapper must be convertible to a string, otherwise an error is raised.

Examples

iex> Enum.map_join([1, 2, 3], &(&1 * 2))
"246"

iex> Enum.map_join([1, 2, 3], " = ", &(&1 * 2))
"2 = 4 = 6"
Link to this function

map_reduce(enumerable, acc, fun)

View Source
@spec map_reduce(t(), acc(), (element(), acc() -> {element(), acc()})) ::
  {list(), acc()}

Invokes the given function to each element in the enumerable to reduce it to a single element, while keeping an accumulator.

Returns a tuple where the first element is the mapped enumerable and the second one is the final accumulator.

The function, fun, receives two arguments: the first one is the element, and the second one is the accumulator. fun must return a tuple with two elements in the form of {result, accumulator}.

For maps, the first tuple element must be a {key, value} tuple.

Examples

iex> Enum.map_reduce([1, 2, 3], 0, fn x, acc -> {x * 2, x + acc} end)
{[2, 4, 6], 6}
Link to this function

max(enumerable, sorter \\ &>=/2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

View Source
@spec max(t(), (element(), element() -> boolean()) | module(), (() -> empty_result)) ::
  element() | empty_result
when empty_result: any()

Returns the maximal element in the enumerable according to Erlang's term ordering.

By default, the comparison is done with the >= sorter function. If multiple elements are considered maximal, the first one that was found is returned. If you want the last element considered maximal to be returned, the sorter function should not return true for equal elements.

If the enumerable is empty, the provided empty_fallback is called. The default empty_fallback raises Enum.EmptyError.

Examples

iex> Enum.max([1, 2, 3])
3

The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. For example:

iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]])
~D[2017-03-31]

In the example above, max/2 returned March 31st instead of April 1st because the structural comparison compares the day before the year. For this reason, most structs provide a "compare" function, such as Date.compare/2, which receives two structs and returns :lt (less-than), :eq (equal to), and :gt (greater-than). If you pass a module as the sorting function, Elixir will automatically use the compare/2 function of said module:

iex> Enum.max([~D[2017-03-31], ~D[2017-04-01]], Date)
~D[2017-04-01]

Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback:

iex> Enum.max([], &>=/2, fn -> 0 end)
0
Link to this function

max_by(enumerable, fun, sorter \\ &>=/2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

View Source
@spec max_by(
  t(),
  (element() -> any()),
  (element(), element() -> boolean()) | module(),
  (() -> empty_result)
) :: element() | empty_result
when empty_result: any()

Returns the maximal element in the enumerable as calculated by the given fun.

By default, the comparison is done with the >= sorter function. If multiple elements are considered maximal, the first one that was found is returned. If you want the last element considered maximal to be returned, the sorter function should not return true for equal elements.

Calls the provided empty_fallback function and returns its value if enumerable is empty. The default empty_fallback raises Enum.EmptyError.

Examples

iex> Enum.max_by(["a", "aa", "aaa"], fn x -> String.length(x) end)
"aaa"

iex> Enum.max_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1)
"aaa"

The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. Therefore, if you want to compare structs, most structs provide a "compare" function, such as Date.compare/2, which receives two structs and returns :lt (less-than), :eq (equal to), and :gt (greater-than). If you pass a module as the sorting function, Elixir will automatically use the compare/2 function of said module:

iex> users = [
...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
...>   %{name: "Turing", birthday: ~D[1912-06-23]}
...> ]
iex> Enum.max_by(users, &(&1.birthday), Date)
%{name: "Ellis", birthday: ~D[1943-05-11]}

Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback:

iex> Enum.max_by([], &String.length/1, fn -> nil end)
nil
Link to this function

member?(enumerable, element)

View Source
@spec member?(t(), element()) :: boolean()

Checks if element exists within the enumerable.

Membership is tested with the match (===/2) operator.

Examples

iex> Enum.member?(1..10, 5)
true
iex> Enum.member?(1..10, 5.0)
false

iex> Enum.member?([1.0, 2.0, 3.0], 2)
false
iex> Enum.member?([1.0, 2.0, 3.0], 2.000)
true

iex> Enum.member?([:a, :b, :c], :d)
false

When not called whithin guards, the in and not in operators work by using this function.

Link to this function

min(enumerable, sorter \\ &<=/2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

View Source
@spec min(t(), (element(), element() -> boolean()) | module(), (() -> empty_result)) ::
  element() | empty_result
when empty_result: any()

Returns the minimal element in the enumerable according to Erlang's term ordering.

By default, the comparison is done with the <= sorter function. If multiple elements are considered minimal, the first one that was found is returned. If you want the last element considered minimal to be returned, the sorter function should not return true for equal elements.

If the enumerable is empty, the provided empty_fallback is called. The default empty_fallback raises Enum.EmptyError.

Examples

iex> Enum.min([1, 2, 3])
1

The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. For example:

iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]])
~D[2017-04-01]

In the example above, min/2 returned April 1st instead of March 31st because the structural comparison compares the day before the year. For this reason, most structs provide a "compare" function, such as Date.compare/2, which receives two structs and returns :lt (less-than), :eq (equal to), and :gt (greater-than). If you pass a module as the sorting function, Elixir will automatically use the compare/2 function of said module:

iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]], Date)
~D[2017-03-31]

Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback:

iex> Enum.min([], fn -> 0 end)
0
Link to this function

min_by(enumerable, fun, sorter \\ &<=/2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

View Source
@spec min_by(
  t(),
  (element() -> any()),
  (element(), element() -> boolean()) | module(),
  (() -> empty_result)
) :: element() | empty_result
when empty_result: any()

Returns the minimal element in the enumerable as calculated by the given fun.

By default, the comparison is done with the <= sorter function. If multiple elements are considered minimal, the first one that was found is returned. If you want the last element considered minimal to be returned, the sorter function should not return true for equal elements.

Calls the provided empty_fallback function and returns its value if enumerable is empty. The default empty_fallback raises Enum.EmptyError.

Examples

iex> Enum.min_by(["a", "aa", "aaa"], fn x -> String.length(x) end)
"a"

iex> Enum.min_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1)
"a"

The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. Therefore, if you want to compare structs, most structs provide a "compare" function, such as Date.compare/2, which receives two structs and returns :lt (less-than), :eq (equal to), and :gt (greater-than). If you pass a module as the sorting function, Elixir will automatically use the compare/2 function of said module:

iex> users = [
...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
...>   %{name: "Turing", birthday: ~D[1912-06-23]}
...> ]
iex> Enum.min_by(users, &(&1.birthday), Date)
%{name: "Lovelace", birthday: ~D[1815-12-10]}

Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback:

iex> Enum.min_by([], &String.length/1, fn -> nil end)
nil
Link to this function

min_max(enumerable, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

View Source
@spec min_max(t(), (() -> empty_result)) :: {element(), element()} | empty_result
when empty_result: any()

Returns a tuple with the minimal and the maximal elements in the enumerable according to Erlang's term ordering.

If multiple elements are considered maximal or minimal, the first one that was found is returned.

Calls the provided empty_fallback function and returns its value if enumerable is empty. The default empty_fallback raises Enum.EmptyError.

Examples

iex> Enum.min_max([2, 3, 1])
{1, 3}

iex> Enum.min_max([], fn -> {nil, nil} end)
{nil, nil}
Link to this function

min_max_by(enumerable, fun, sorter_or_empty_fallback \\ &</2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

View Source
@spec min_max_by(
  t(),
  (element() -> any()),
  (element(), element() -> boolean()) | module(),
  (() -> empty_result)
) :: {element(), element()} | empty_result
when empty_result: any()

Returns a tuple with the minimal and the maximal elements in the enumerable as calculated by the given function.

If multiple elements are considered maximal or minimal, the first one that was found is returned.

Examples

iex> Enum.min_max_by(["aaa", "bb", "c"], fn x -> String.length(x) end)
{"c", "aaa"}

iex> Enum.min_max_by(["aaa", "a", "bb", "c", "ccc"], &String.length/1)
{"a", "aaa"}

iex> Enum.min_max_by([], &String.length/1, fn -> {nil, nil} end)
{nil, nil}

The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. Therefore, if you want to compare structs, most structs provide a "compare" function, such as Date.compare/2, which receives two structs and returns :lt (less-than), :eq (equal to), and :gt (greater-than). If you pass a module as the sorting function, Elixir will automatically use the compare/2 function of said module:

iex> users = [
...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
...>   %{name: "Turing", birthday: ~D[1912-06-23]}
...> ]
iex> Enum.min_max_by(users, &(&1.birthday), Date)
{
  %{name: "Lovelace", birthday: ~D[1815-12-10]},
  %{name: "Ellis", birthday: ~D[1943-05-11]}
}

Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback:

iex> Enum.min_max_by([], &String.length/1, fn -> nil end)
nil
@spec random(t()) :: element()

Returns a random element of an enumerable.

Raises Enum.EmptyError if enumerable is empty.

This function uses Erlang's :rand module to calculate the random value. Check its documentation for setting a different random algorithm or a different seed.

The implementation is based on the reservoir sampling algorithm. It assumes that the sample being returned can fit into memory; the input enumerable doesn't have to, as it is traversed just once.

If a range is passed into the function, this function will pick a random value between the range limits, without traversing the whole range (thus executing in constant time and constant memory).

Examples

The examples below use the :exrop pseudorandom algorithm since it's the default from Erlang/OTP 20, however if you are using Erlang/OTP 22 or above then :exsss is the default algorithm. If you are using :exsplus, then please update, as this algorithm is deprecated since Erlang/OTP 20.

# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exrop, {101, 102, 103})
iex> Enum.random([1, 2, 3])
3
iex> Enum.random([1, 2, 3])
2
iex> Enum.random(1..1_000)
846
@spec reduce(t(), (element(), acc() -> acc())) :: acc()

Invokes fun for each element in the enumerable with the accumulator.

Raises Enum.EmptyError if enumerable is empty.

The first element of the enumerable is used as the initial value of the accumulator. Then the function is invoked with the next element and the accumulator. The result returned by the function is used as the accumulator for the next iteration, recursively. When the enumerable is done, the last accumulator is returned.

Since the first element of the enumerable is used as the initial value of the accumulator, fun will only be executed n - 1 times where n is the length of the enumerable. This function won't call the specified function for enumerables that are one-element long.

If you wish to use another value for the accumulator, use Enum.reduce/3.

Examples

iex> Enum.reduce([1, 2, 3, 4], fn x, acc -> x * acc end)
24
Link to this function

reduce(enumerable, acc, fun)

View Source
@spec reduce(t(), any(), (element(), acc() -> acc())) :: acc()

Invokes fun for each element in the enumerable with the accumulator.

The initial value of the accumulator is acc. The function is invoked for each element in the enumerable with the accumulator. The result returned by the function is used as the accumulator for the next iteration. The function returns the last accumulator.

Examples

iex> Enum.reduce([1, 2, 3], 0, fn x, acc -> x + acc end)
6

Reduce as a building block

Reduce (sometimes called fold) is a basic building block in functional programming. Almost all of the functions in the Enum module can be implemented on top of reduce. Those functions often rely on other operations, such as Enum.reverse/1, which are optimized by the runtime.

For example, we could implement map/2 in terms of reduce/3 as follows:

def my_map(enumerable, fun) do
  enumerable
  |> Enum.reduce([], fn x, acc -> [fun.(x) | acc] end)
  |> Enum.reverse()
end

In the example above, Enum.reduce/3 accumulates the result of each call to fun into a list in reverse order, which is correctly ordered at the end by calling Enum.reverse/1.

Implementing functions like map/2, filter/2 and others are a good exercise for understanding the power behind Enum.reduce/3. When an operation cannot be expressed by any of the functions in the Enum module, developers will most likely resort to reduce/3.

Link to this function

reduce_while(enumerable, acc, fun)

View Source
@spec reduce_while(t(), any(), (element(), any() -> {:cont, any()} | {:halt, any()})) ::
  any()

Reduces enumerable until fun returns {:halt, term}.

The return value for fun is expected to be

  • {:cont, acc} to continue the reduction with acc as the new accumulator or
  • {:halt, acc} to halt the reduction

If fun returns {:halt, acc} the reduction is halted and the function returns acc. Otherwise, if the enumerable is exhausted, the function returns the accumulator of the last {:cont, acc}.

Examples

iex> Enum.reduce_while(1..100, 0, fn x, acc ->
...>   if x < 5, do: {:cont, acc + x}, else: {:halt, acc}
...> end)
10
iex> Enum.reduce_while(1..100, 0, fn x, acc ->
...>   if x > 0, do: {:cont, acc + x}, else: {:halt, acc}
...> end)
5050
@spec reject(t(), (element() -> as_boolean(term()))) :: list()

Returns a list of elements in enumerable excluding those for which the function fun returns a truthy value.

See also filter/2.

Examples

iex> Enum.reject([1, 2, 3], fn x -> rem(x, 2) == 0 end)
[1, 3]
@spec reverse(t()) :: list()

Returns a list of elements in enumerable in reverse order.

Examples

iex> Enum.reverse([1, 2, 3])
[3, 2, 1]
Link to this function

reverse(enumerable, tail)

View Source
@spec reverse(t(), t()) :: list()

Reverses the elements in enumerable, appends the tail, and returns it as a list.

This is an optimization for enumerable |> Enum.reverse() |> Enum.concat(tail).

Examples

iex> Enum.reverse([1, 2, 3], [4, 5, 6])
[3, 2, 1, 4, 5, 6]
Link to this function

reverse_slice(enumerable, start_index, count)

View Source
@spec reverse_slice(t(), non_neg_integer(), non_neg_integer()) :: list()

Reverses the enumerable in the range from initial start_index through count elements.

If count is greater than the size of the rest of the enumerable, then this function will reverse the rest of the enumerable.

Examples

iex> Enum.reverse_slice([1, 2, 3, 4, 5, 6], 2, 4)
[1, 2, 6, 5, 4, 3]
@spec scan(t(), (element(), any() -> any())) :: list()

Applies the given function to each element in the enumerable, storing the result in a list and passing it as the accumulator for the next computation. Uses the first element in the enumerable as the starting value.

Examples

iex> Enum.scan(1..5, &(&1 + &2))
[1, 3, 6, 10, 15]
Link to this function

scan(enumerable, acc, fun)

View Source
@spec scan(t(), any(), (element(), any() -> any())) :: list()

Applies the given function to each element in the enumerable, storing the result in a list and passing it as the accumulator for the next computation. Uses the given acc as the starting value.

Examples

iex> Enum.scan(1..5, 0, &(&1 + &2))
[1, 3, 6, 10, 15]
@spec shuffle(t()) :: list()

Returns a list with the elements of enumerable shuffled.

This function uses Erlang's :rand module to calculate the random value. Check its documentation for setting a different random algorithm or a different seed.

Examples

The examples below use the :exrop pseudorandom algorithm since it's the default from Erlang/OTP 20, however if you are using Erlang/OTP 22 or above then :exsss is the default algorithm. If you are using :exsplus, then please update, as this algorithm is deprecated since Erlang/OTP 20.

# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exrop, {1, 2, 3})
iex> Enum.shuffle([1, 2, 3])
[3, 1, 2]
iex> Enum.shuffle([1, 2, 3])
[1, 3, 2]
Link to this function

slice(enumerable, index_range)

View Source (since 1.6.0)
@spec slice(t(), Range.t()) :: list()

Returns a subset list of the given enumerable by index_range.

index_range must be a Range. Given an enumerable, it drops elements before index_range.first (zero-base), then takes elements until element index_range.last (inclusively).

Indexes are normalized, meaning that negative indexes will be counted from the end (for example, -1 means the last element of the enumerable).

If index_range.last is out of bounds, then it is assigned as the index of the last element.

If the normalized index_range.first is out of bounds of the given enumerable, or this one is greater than the normalized index_range.last, then [] is returned.

Examples

iex> Enum.slice(1..100, 5..10)
[6, 7, 8, 9, 10, 11]

iex> Enum.slice(1..10, 5..20)
[6, 7, 8, 9, 10]

# last five elements (negative indexes)
iex> Enum.slice(1..30, -5..-1)
[26, 27, 28, 29, 30]

# last five elements (mixed positive and negative indexes)
iex> Enum.slice(1..30, 25..-1)
[26, 27, 28, 29, 30]

# out of bounds
iex> Enum.slice(1..10, 11..20)
[]

# first is greater than last
iex> Enum.slice(1..10, 6..5)
[]
Link to this function

slice(enumerable, start_index, amount)

View Source
@spec slice(t(), index(), non_neg_integer()) :: list()

Returns a subset list of the given enumerable, from start_index (zero-based) with amount number of elements if available.

Given an enumerable, it drops elements right before element start_index, then takes amount of elements, returning as many elements as possible if there are not enough elements.

A negative start_index can be passed, which means the enumerable is enumerated once and the index is counted from the end (for example, -1 starts slicing from the last element).

It returns [] if amount is 0 or if start_index is out of bounds.

Examples

iex> Enum.slice(1..100, 5, 10)
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

# amount to take is greater than the number of elements
iex> Enum.slice(1..10, 5, 100)
[6, 7, 8, 9, 10]

iex> Enum.slice(1..10, 5, 0)
[]

# using a negative start index
iex> Enum.slice(1..10, -6, 3)
[5, 6, 7]

# out of bound start index (positive)
iex> Enum.slice(1..10, 10, 5)
[]

# out of bound start index (negative)
iex> Enum.slice(1..10, -11, 5)
[]
@spec sort(t()) :: list()

Sorts the enumerable according to Erlang's term ordering.

This function uses the merge sort algorithm. Do not use this function to sort structs, see sort/2 for more information.

Examples

iex> Enum.sort([3, 2, 1])
[1, 2, 3]
@spec sort(
  t(),
  (element(), element() -> boolean())
  | :asc
  | :desc
  | module()
  | {:asc | :desc, module()}
) :: list()

Sorts the enumerable by the given function.

This function uses the merge sort algorithm. The given function should compare two arguments, and return true if the first argument precedes or is in the same place as the second one.

Examples

iex> Enum.sort([1, 2, 3], &(&1 >= &2))
[3, 2, 1]

The sorting algorithm will be stable as long as the given function returns true for values considered equal:

iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) <= byte_size(&2)))
["of", "some", "kind", "monster"]

If the function does not return true for equal values, the sorting is not stable and the order of equal terms may be shuffled. For example:

iex> Enum.sort(["some", "kind", "of", "monster"], &(byte_size(&1) < byte_size(&2)))
["of", "kind", "some", "monster"]

Ascending and descending

sort/2 allows a developer to pass :asc or :desc as the sorting function, which is a convenience for <=/2 and >=/2 respectively.

iex> Enum.sort([2, 3, 1], :asc)
[1, 2, 3]
iex> Enum.sort([2, 3, 1], :desc)
[3, 2, 1]

Sorting structs

Do not use </2, <=/2, >/2, >=/2 and friends when sorting structs. That's because the built-in operators above perform structural comparison and not a semantic one. Imagine we sort the following list of dates:

iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
iex> Enum.sort(dates)
[~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]

Note that the returned result is incorrect, because sort/1 by default uses <=/2, which will compare their structure. When comparing structures, the fields are compared in alphabetical order, which means the dates above will be compared by day, month and then year, which is the opposite of what we want.

For this reason, most structs provide a "compare" function, such as Date.compare/2, which receives two structs and returns :lt (less-than), :eq (equal to), and :gt (greater-than). If you pass a module as the sorting function, Elixir will automatically use the compare/2 function of said module:

iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
iex> Enum.sort(dates, Date)
[~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]]

To retrieve all dates in descending order, you can wrap the module in a tuple with :asc or :desc as first element:

iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
iex> Enum.sort(dates, {:asc, Date})
[~D[2019-01-01], ~D[2019-06-06], ~D[2020-03-02]]
iex> dates = [~D[2019-01-01], ~D[2020-03-02], ~D[2019-06-06]]
iex> Enum.sort(dates, {:desc, Date})
[~D[2020-03-02], ~D[2019-06-06], ~D[2019-01-01]]
Link to this function

sort_by(enumerable, mapper, sorter \\ &<=/2)

View Source
@spec sort_by(
  t(),
  (element() -> mapped_element),
  (element(), element() -> boolean())
  | :asc
  | :desc
  | module()
  | {:asc | :desc, module()}
) :: list()
when mapped_element: element()

Sorts the mapped results of the enumerable according to the provided sorter function.

This function maps each element of the enumerable using the provided mapper function. The enumerable is then sorted by the mapped elements using the sorter function, which defaults to Kernel.<=/2.

sort_by/3 differs from sort/2 in that it only calculates the comparison value for each element in the enumerable once instead of once for each element in each comparison. If the same function is being called on both elements, it's more efficient to use sort_by/3.

Examples

Using the default sorter of <=/2:

iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1)
["of", "some", "kind", "monster"]

Sorting by multiple properties - first by size, then by first letter (this takes advantage of the fact that tuples are compared element-by-element):

iex> Enum.sort_by(["some", "kind", "of", "monster"], &{byte_size(&1), String.first(&1)})
["of", "kind", "some", "monster"]

Similar to sort/2, you can pass a custom sorter:

iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1, &>=/2)
["monster", "some", "kind", "of"]

Or use :asc and :desc:

iex> Enum.sort_by(["some", "kind", "of", "monster"], &byte_size/1, :desc)
["monster", "some", "kind", "of"]

As in sort/2, avoid using the default sorting function to sort structs, as by default it performs structural comparison instead of a semantic one. In such cases, you shall pass a sorting function as third element or any module that implements a compare/2 function. For example, to sort users by their birthday in both ascending and descending order respectively:

iex> users = [
...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
...>   %{name: "Turing", birthday: ~D[1912-06-23]}
...> ]
iex> Enum.sort_by(users, &(&1.birthday), Date)
[
  %{name: "Lovelace", birthday: ~D[1815-12-10]},
  %{name: "Turing", birthday: ~D[1912-06-23]},
  %{name: "Ellis", birthday: ~D[1943-05-11]}
]
iex> Enum.sort_by(users, &(&1.birthday), {:desc, Date})
[
  %{name: "Ellis", birthday: ~D[1943-05-11]},
  %{name: "Turing", birthday: ~D[1912-06-23]},
  %{name: "Lovelace", birthday: ~D[1815-12-10]}
]
Link to this function

split(enumerable, count)

View Source
@spec split(t(), integer()) :: {list(), list()}

Splits the enumerable into two enumerables, leaving count elements in the first one.

If count is a negative number, it starts counting from the back to the beginning of the enumerable.

Be aware that a negative count implies the enumerable will be enumerated twice: once to calculate the position, and a second time to do the actual splitting.

Examples

iex> Enum.split([1, 2, 3], 2)
{[1, 2], [3]}

iex> Enum.split([1, 2, 3], 10)
{[1, 2, 3], []}

iex> Enum.split([1, 2, 3], 0)
{[], [1, 2, 3]}

iex> Enum.split([1, 2, 3], -1)
{[1, 2], [3]}

iex> Enum.split([1, 2, 3], -5)
{[], [1, 2, 3]}
Link to this function

split_while(enumerable, fun)

View Source
@spec split_while(t(), (element() -> as_boolean(term()))) :: {list(), list()}

Splits enumerable in two at the position of the element for which fun returns a falsy value (false or nil) for the first time.

It returns a two-element tuple with two lists of elements. The element that triggered the split is part of the second list.

Examples

iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 3 end)
{[1, 2], [3, 4]}

iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 0 end)
{[], [1, 2, 3, 4]}

iex> Enum.split_while([1, 2, 3, 4], fn x -> x > 0 end)
{[1, 2, 3, 4], []}
Link to this function

split_with(enumerable, fun)

View Source (since 1.4.0)
@spec split_with(t(), (element() -> as_boolean(term()))) :: {list(), list()}

Splits the enumerable in two lists according to the given function fun.

Splits the given enumerable in two lists by calling fun with each element in the enumerable as its only argument. Returns a tuple with the first list containing all the elements in enumerable for which applying fun returned a truthy value, and a second list with all the elements for which applying fun returned a falsy value (false or nil).

The elements in both the returned lists are in the same relative order as they were in the original enumerable (if such enumerable was ordered, like a list). See the examples below.

Examples

iex> Enum.split_with([5, 4, 3, 2, 1, 0], fn x -> rem(x, 2) == 0 end)
{[4, 2, 0], [5, 3, 1]}

iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v < 0 end)
{[b: -2, d: -3], [a: 1, c: 1]}

iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v > 50 end)
{[], [a: 1, b: -2, c: 1, d: -3]}

iex> Enum.split_with(%{}, fn {_k, v} -> v > 50 end)
{[], []}
@spec sum(t()) :: number()

Returns the sum of all elements.

Raises ArithmeticError if enumerable contains a non-numeric value.

Examples

iex> Enum.sum([1, 2, 3])
6
Link to this function

take(enumerable, amount)

View Source
@spec take(t(), integer()) :: list()

Takes an amount of elements from the beginning or the end of the enumerable.

If a positive amount is given, it takes the amount elements from the beginning of the enumerable.

If a negative amount is given, the amount of elements will be taken from the end. The enumerable will be enumerated once to retrieve the proper index and the remaining calculation is performed from the end.

If amount is 0, it returns [].

Examples

iex> Enum.take([1, 2, 3], 2)
[1, 2]

iex> Enum.take([1, 2, 3], 10)
[1, 2, 3]

iex> Enum.take([1, 2, 3], 0)
[]

iex> Enum.take([1, 2, 3], -1)
[3]
Link to this function

take_every(enumerable, nth)

View Source
@spec take_every(t(), non_neg_integer()) :: list()

Returns a list of every nth element in the enumerable, starting with the first element.

The first element is always included, unless nth is 0.

The second argument specifying every nth element must be a non-negative integer.

Examples

iex> Enum.take_every(1..10, 2)
[1, 3, 5, 7, 9]

iex> Enum.take_every(1..10, 0)
[]

iex> Enum.take_every([1, 2, 3], 1)
[1, 2, 3]
Link to this function

take_random(enumerable, count)

View Source
@spec take_random(t(), non_neg_integer()) :: list()

Takes count random elements from enumerable.

Note that this function will traverse the whole enumerable to get the random sublist.

See random/1 for notes on implementation and random seed.

Examples

# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exrop, {1, 2, 3})
iex> Enum.take_random(1..10, 2)
[7, 2]
iex> Enum.take_random(?a..?z, 5)
'hypnt'
Link to this function

take_while(enumerable, fun)

View Source
@spec take_while(t(), (element() -> as_boolean(term()))) :: list()

Takes the elements from the beginning of the enumerable while fun returns a truthy value.

Examples

iex> Enum.take_while([1, 2, 3], fn x -> x < 3 end)
[1, 2]
@spec to_list(t()) :: [element()]

Converts enumerable to a list.

Examples

iex> Enum.to_list(1..3)
[1, 2, 3]
@spec uniq(t()) :: list()

Enumerates the enumerable, removing all duplicated elements.

Examples

iex> Enum.uniq([1, 2, 3, 3, 2, 1])
[1, 2, 3]
Link to this function

uniq_by(enumerable, fun)

View Source
@spec uniq_by(t(), (element() -> term())) :: list()

Enumerates the enumerable, by removing the elements for which function fun returned duplicate elements.

The function fun maps every element to a term. Two elements are considered duplicates if the return value of fun is equal for both of them.

The first occurrence of each element is kept.

Example

iex> Enum.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end)
[{1, :x}, {2, :y}]

iex> Enum.uniq_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn {_, y} -> y end)
[a: {:tea, 2}, c: {:coffee, 1}]
@spec unzip(t()) :: {[element()], [element()]}

Opposite of zip/2. Extracts two-element tuples from the given enumerable and groups them together.

It takes an enumerable with elements being two-element tuples and returns a tuple with two lists, each of which is formed by the first and second element of each tuple, respectively.

This function fails unless enumerable is or can be converted into a list of tuples with exactly two elements in each tuple.

Examples

iex> Enum.unzip([{:a, 1}, {:b, 2}, {:c, 3}])
{[:a, :b, :c], [1, 2, 3]}

iex> Enum.unzip(%{a: 1, b: 2})
{[:a, :b], [1, 2]}
Link to this function

with_index(enumerable, offset \\ 0)

View Source
@spec with_index(t(), integer()) :: [{element(), index()}]

Returns the enumerable with each element wrapped in a tuple alongside its index.

If an offset is given, we will index from the given offset instead of from zero.

Examples

iex> Enum.with_index([:a, :b, :c])
[a: 0, b: 1, c: 2]

iex> Enum.with_index([:a, :b, :c], 3)
[a: 3, b: 4, c: 5]
Link to this function

zip(enumerables)

View Source (since 1.4.0)
@spec zip(enumerables) :: [tuple()] when enumerables: [t()] | t()

Zips corresponding elements from a finite collection of enumerables into one list of tuples.

The zipping finishes as soon as any enumerable in the given collection completes.

Examples

iex> Enum.zip([[1, 2, 3], [:a, :b, :c], ["foo", "bar", "baz"]])
[{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}]

iex> Enum.zip([[1, 2, 3, 4, 5], [:a, :b, :c]])
[{1, :a}, {2, :b}, {3, :c}]
Link to this function

zip(enumerable1, enumerable2)

View Source
@spec zip(t(), t()) :: [{any(), any()}]

Zips corresponding elements from two enumerables into one list of tuples.

The zipping finishes as soon as any enumerable completes.

Examples

iex> Enum.zip([1, 2, 3], [:a, :b, :c])
[{1, :a}, {2, :b}, {3, :c}]

iex> Enum.zip([1, 2, 3, 4, 5], [:a, :b, :c])
[{1, :a}, {2, :b}, {3, :c}]