Spec-Zone.ru › Elixir 1.9

Перечисление

Предоставляет набор алгоритмов для работы со списками.

В Elixir перечислимый тип — это любой тип данных, который реализует протокол Enumerable. Listы ([1, 2, 3]), Mapы (%{foo: 1, bar: 2}) и Rangeы (1..3) — это распространенные типы данных, используемые в качестве перечислимых:

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}]

Однако в языке существует множество других перечислимых типов, таких как MapSetы и тип данных, возвращаемый File.stream!/3, который позволяет обрабатывать файл так, как будто это перечислимый тип.

Функции в этом модуле работают за линейное время. Это означает, что время выполнения операции увеличивается пропорционально длине перечислимого типа. Это ожидается для операций, таких как Enum.map/2. В конце концов, если мы хотим пройти по каждому элементу списка, то чем длиннее список, тем больше элементов нам нужно пройти, и тем дольше это займет.

Такое линейное поведение также ожидается для операций, таких как count/1, member?/2, at/2 и аналогичных. Хотя Elixir позволяет типам данных предоставлять эффективные варианты для таких операций, вы не должны ожидать, что они всегда будут доступны, так как модуль Enum предназначен для работы с широким спектром типов данных, и не все типы данных могут обеспечивать оптимизированное поведение.

Наконец, обратите внимание, что функции в модуле Enum являются жадными: они пройдут по перечислимому типу сразу же после вызова. Это особенно опасно при работе с бесконечными перечислимыми типами. В таких случаях вы должны использовать модуль Stream, который позволяет вам лениво выражать вычисления, не проходя по коллекциям, и работать с потенциально бесконечными коллекциями. Обратитесь к модулю Stream для примеров и документации.

Резюме

Типы

acc()
default()
element()
index()

Индекс, начинающийся с нуля. Также может быть отрицательным целым числом.

t()

Функции

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

Возвращает true если fun.(element) истинно для всех элементов в enumerable.

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

Возвращает true если fun.(element) истинно хотя бы для одного элемента в enumerable.

at(enumerable, index, default \\ nil)

Находит элемент по заданному index (нумерация с нуля).

chunk_by(enumerable, fun)

Разбивает перечислимый объект на группы по каждому элементу, для которого fun возвращает новое значение.

chunk_every(enumerable, count)

Сокращение для chunk_every(enumerable, count, count).

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

Возвращает список списков, содержащих по count элементов каждый, где каждый новый фрагмент начинается через step элементов в enumerable.

chunk_while(enumerable, acc, chunk_fun, after_fun)

Разбивает перечислимый объект на куски с точным управлением, когда каждый фрагмент отправляется.

concat(enumerables)

Принимая на вход перечислимый объект перечислимых объектов, конкатенирует enumerables в один список.

concat(left, right)

Конкатенирует перечислимый объект слева с перечислимым объектом справа.

count(enumerable)

Возвращает размер enumerable.

count(enumerable, fun)

Возвращает количество элементов в enumerable, для которых fun возвращает истинное значение.

dedup(enumerable)

Перечисляет enumerable, возвращая список, где все последовательные дублирующиеся элементы сворачиваются в один элемент.

dedup_by(enumerable, fun)

Перечисляет enumerable, возвращая список, где все последовательные дублирующиеся элементы сворачиваются в один элемент.

drop(enumerable, amount)

Опускает amount элементов из enumerable.

drop_every(enumerable, nth)

Возвращает список каждого nth элемента в enumerable с пропусками, начиная с первого элемента.

drop_while(enumerable, fun)

Опускает элементы в начале enumerable пока fun возвращает истинное значение.

each(enumerable, fun)

Вызывает заданную fun для каждого элемента в enumerable.

empty?(enumerable)

Определяет, является ли enumerable пустым.

fetch(enumerable, index)

Находит элемент по заданному index (нумерация с нуля).

fetch!(enumerable, index)

Находит элемент по заданному index (нумерация с нуля).

filter(enumerable, fun)

Фильтровать enumerable, т.е. возвращает только те элементы, для которых fun возвращает истинное значение.

find(enumerable, default \\ nil, fun)

Возвращает первый элемент, для которого fun возвращает истинное значение. Если такой элемент не найден, возвращает default.

find_index(enumerable, fun)

Аналогично find/3, но возвращает индекс (нумерация с нуля) элемента вместо самого элемента.

find_value(enumerable, default \\ nil, fun)

Аналогично find/3, но возвращает значение вызова функции вместо самого элемента.

flat_map(enumerable, fun)

Применяет данную fun к enumerable и сплющивает результат.

flat_map_reduce(enumerable, acc, fun)

Применяет и сворачивает перечислимый объект, сплющивая полученные результаты (только один уровень глубины).

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

Разбивает перечислимый объект на группы, основанные на key_fun.

intersperse(enumerable, element)

Вставляет element между каждым элементом перечисления.

into(enumerable, collectable)

Вставляет данный enumerable в collectable.

into(enumerable, collectable, transform)

Вставляет данный enumerable в collectable в соответствии с функцией преобразования.

join(enumerable, joiner \\ "")

Объединяет данный enumerable в строку, используя joiner в качестве разделителя.

map(enumerable, fun)

Возвращает список, где каждый элемент является результатом вызова fun для каждого соответствующего элемента enumerable.

map_every(enumerable, nth, fun)

Возвращает список результатов вызова fun для каждого nth элемента enumerable, начиная с первого элемента.

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

Преобразует и объединяет данный enumerable за один проход.

map_reduce(enumerable, acc, fun)

Вызывает заданную функцию для каждого элемента в enumerable для сведения его к одному элементу, сохраняя при этом аккумулирующее значение.

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

Возвращает максимальный элемент в enumerable в соответствии с порядком Erlang.

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

Возвращает максимальный элемент в enumerable, рассчитанный с помощью заданной функции.

member?(enumerable, element)

Проверяет, существует ли element в enumerable.

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

Возвращает минимальный элемент в enumerable в соответствии с порядком Erlang.

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

Возвращает минимальный элемент в enumerable, рассчитанный с помощью заданной функции.

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

Возвращает кортеж с минимальным и максимальным элементами в перечислимом объекте в соответствии с порядком Erlang.

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

Возвращает кортеж с минимальным и максимальным элементами в перечислимом объекте, рассчитанными с помощью заданной функции.

random(enumerable)

Возвращает случайный элемент перечислимого объекта.

reduce(enumerable, fun)

Вызывает fun для каждого элемента в перечислимом объекте с накопителем.

reduce(enumerable, acc, fun)

Вызывает fun для каждого элемента в перечислимом объекте с накопителем.

reduce_while(enumerable, acc, fun)

Рекурсивно уменьшает перечислимый объект, пока fun не вернёт {:halt, term}.

reject(enumerable, fun)

Возвращает список элементов из перечислимого объекта, исключая те, для которых функция fun возвращает истинное значение.

reverse(enumerable)

Возвращает список элементов из перечислимого объекта в обратном порядке.

reverse(enumerable, tail)

Инвертирует элементы перечислимого объекта, добавляет tail, и возвращает их как список.

reverse_slice(enumerable, start_index, count)

Инвертирует часть перечислимого объекта в диапазоне от начального start_index до count элементов.

scan(enumerable, fun)

Применяет данную функцию к каждому элементу в перечислимом объекте, сохраняя результат в списке и передавая его как накопитель для следующего вычисления. Использует первый элемент в перечислимом объекте как начальное значение.

scan(enumerable, acc, fun)

Применяет данную функцию к каждому элементу в перечислимом объекте, сохраняя результат в списке и передавая его как накопитель для следующего вычисления. Использует заданное acc в качестве начального значения.

shuffle(enumerable)

Возвращает список с перемешанными элементами перечислимого объекта.

slice(enumerable, index_range)

Возвращает подмножество списка заданного перечислимого объекта, используя указанный диапазон.

slice(enumerable, start_index, amount)

Возвращает подмножество списка заданного перечислимого объекта, начиная с start_index (нумерация с нуля), с amount количеством элементов, если доступно.

sort(enumerable)

Сортирует перечислимый объект в соответствии с порядком Erlang.

sort(enumerable, fun)

Сортирует перечислимый объект с помощью заданной функции.

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

Сортирует отсортированные результаты перечислимого объекта согласно предоставленной функции сортировки.

split(enumerable, count)

Разделяет перечислимый объект на два перечислимых объекта, оставляя count элементов в первом.

split_while(enumerable, fun)

Разделяет перечислимый объект на две части по позиции элемента, для которого fun в первый раз возвращает ложное значение (false или nil).

split_with(enumerable, fun)

Разделяет перечислимый объект на два списка в соответствии с заданной функцией fun.

sum(enumerable)

Возвращает сумму всех элементов.

take(enumerable, amount)

Извлекает указанное количество элементов с начала или конца перечислимого объекта.

take_every(enumerable, nth)

Возвращает список каждого nth элемента в перечислимом объекте, начиная с первого.

take_random(enumerable, count)

Извлекает count случайных элементов из перечислимого объекта.

take_while(enumerable, fun)

Извлекает элементы с начала перечислимого объекта, пока fun возвращает истинное значение.

to_list(enumerable)

Преобразует перечислимый объект в список.

uniq(enumerable)

Перечисляет перечислимый объект, удаляя все дублирующие элементы.

uniq_by(enumerable, fun)

Перечисляет перечислимый объект, удаляя элементы, для которых функция fun возвращает дублирующиеся элементы.

unzip(enumerable)

Обратное zip/2. Извлекает кортежи из двух элементов из заданного перечислимого объекта и группирует их.

with_index(enumerable, offset \\ 0)

Возвращает перечислимый объект, где каждый элемент обернут в кортеж вместе с его индексом.

zip(enumerables)

Комбинирует соответствующие элементы из конечного набора перечислимых объектов в один список кортежей.

zip(enumerable1, enumerable2)

Комбинирует соответствующие элементы из двух перечислимых объектов в один список кортежей.

Типы

acc()

Спецификации

acc() :: any()

default()

Спецификации

default() :: any()

element()

Спецификации

element() :: any()

index()

Спецификации

index() :: integer()

Индекс, основанный на нуле. Также может быть отрицательным целым числом.

t()

Спецификации

t() :: Enumerable.t()

Функции

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

Спецификации

all?(t(), (element() -> as_boolean(term()))) :: boolean()

Возвращает true если fun.(element) истинно для всех элементов в enumerable.

Итерирует по enumerable и вызывает fun для каждого элемента. Когда вызов fun возвращает ложное значение (false или nil) итерация немедленно останавливается и возвращается false. Во всех остальных случаях возвращается true.

Примеры

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

Если функция не задана, истинность каждого элемента проверяется во время итерации. Когда элемент имеет ложное значение (false или nil) итерация немедленно останавливается и возвращается false. Во всех остальных случаях возвращается true.

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

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

iex> Enum.all?([])
true

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

Спецификации

any?(t(), (element() -> as_boolean(term()))) :: boolean()

Возвращает true если fun.(element) истинно хотя бы для одного элемента в enumerable.

Итерирует по enumerable и вызывает fun для каждого элемента. Когда вызов fun возвращает истинное значение (ни false, ни nil) итерация немедленно останавливается и возвращается true. Во всех остальных случаях возвращается false.

Примеры

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

Если функция не задана, истинность каждого элемента проверяется во время итерации. Когда элемент имеет истинное значение (ни false, ни nil) итерация немедленно останавливается и возвращается true. Во всех остальных случаях возвращается false.

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

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

iex> Enum.any?([])
false

at(enumerable, index, default \\ nil)

Спецификации

at(t(), index(), default()) :: element() | default()

Находит элемент по заданному index (с нулевой основой).

Возвращает default если index вне границ.

Можно передать отрицательный index, что означает, что enumerable перечисляется один раз, и index считается с конца (например, -1 находит последний элемент).

Примеры

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

chunk_by(enumerable, fun)

Спецификации

chunk_by(t(), (element() -> any())) :: [list()]

Разделяет перечисляемый на каждый элемент, для которого fun возвращает новое значение.

Возвращает список списков.

Примеры

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]]

chunk_every(enumerable, count)

Спецификации

chunk_every(t(), pos_integer()) :: [list()]

Сокращение для chunk_every(enumerable, count, count).

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

Спецификации

chunk_every(t(), pos_integer(), pos_integer(), t() | :discard) :: [list()]

Возвращает список списков, содержащих по count элементов каждый, где каждый новый фрагмент начинается через step элементов в enumerable.

step является необязательным и, если не передан, по умолчанию равен count, то есть фрагменты не перекрываются.

Если последний фрагмент не имеет count элементов для заполнения фрагмента, элементы берутся из leftover для заполнения фрагмента. Если leftover не имеет достаточно элементов для заполнения фрагмента, то возвращается частичный фрагмент с менее чем count элементами.

Если :discard задан в leftover, последний фрагмент отбрасывается, если только он не имеет ровно count элементов.

Примеры

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]]

chunk_while(enumerable, acc, chunk_fun, after_fun)

Спецификации

chunk_while(
  t(),
  acc(),
  (element(), acc() -> {:cont, chunk, acc()} | {:cont, acc()} | {:halt, acc()}),
  (acc() -> {:cont, chunk, acc()} | {:cont, acc()})
) :: Enumerable.t()
when chunk: any()

Разделяет enumerable с тонким контролем, когда каждый фрагмент выводится.

chunk_fun получает текущий элемент и накопитель и должен вернуть {:cont, element, acc} для вывода данного фрагмента и продолжения с накопителем или {:cont, acc} для того, чтобы не выводить ни одного фрагмента и продолжать с возвращаемым накопителем.

after_fun вызывается, когда итерация завершена, и также должен возвращать {:cont, element, acc} или {:cont, acc}.

Возвращает список списков.

Примеры

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]]

concat(enumerables)

Спецификации

concat(t()) :: t()

Учитывая перечисляемый перечисляемых, объединяет enumerables в один список.

Примеры

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]

concat(left, right)

Спецификации

concat(t(), t()) :: t()

Объединяет перечисляемый слева с перечисляемым справа.

Эта функция дает тот же результат, что и оператор Kernel.++/2 для списков.

Примеры

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]

count(enumerable)

Спецификации

count(t()) :: non_neg_integer()

Возвращает размер enumerable.

Примеры

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

count(enumerable, fun)

Спецификации

count(t(), (element() -> as_boolean(term()))) :: non_neg_integer()

Возвращает количество элементов в enumerable, для которых fun возвращает истинное значение.

Примеры

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

dedup(enumerable)

Спецификации

dedup(t()) :: list()

Перечисляет enumerable, возвращая список, в котором все последовательные дубликаты элементов сводятся к одному элементу.

Элементы сравниваются с помощью ===/2.

Если вы хотите удалить все дублирующиеся элементы, независимо от порядка, см. uniq/1.

Примеры

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]

dedup_by(enumerable, fun)

Спецификации

dedup_by(t(), (element() -> term())) :: list()

Перечисляет enumerable, возвращая список, в котором все последовательные дубликаты элементов сводятся к одному элементу.

Функция fun сопоставляет каждый элемент с термином, который используется для определения того, являются ли два элемента дубликатами.

Примеры

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]

drop(enumerable, amount)

Спецификации

drop(t(), integer()) :: list()

Удаляет amount элементов из enumerable.

Если задано отрицательное amount, будет удалено amount последних значений. enumerable будет перечислен один раз для получения правильного индекса, и оставшийся расчет выполняется с конца.

Примеры

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]

drop_every(enumerable, nth)

Спецификации

drop_every(t(), non_neg_integer()) :: list()

Возвращает список, в котором каждый nth элемент в enumerable удален, начиная с первого элемента.

Первый элемент всегда удаляется, если только nth не равно 0.

Второй аргумент, указывающий каждый nth элемент, должен быть неотрицательным целым числом.

Примеры

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)
[]

drop_while(enumerable, fun)

Спецификации

drop_while(t(), (element() -> as_boolean(term()))) :: list()

Удаляет элементы в начале enumerable, пока fun возвращает истинное значение.

Примеры

iex> Enum.drop_while([1, 2, 3, 2, 1], fn x -> x < 3 end)
[3, 2, 1]

each(enumerable, fun)

Спецификации

each(t(), (element() -> any())) :: :ok

Вызывает заданную fun для каждого элемента в enumerable.

Возвращает :ok.

Примеры

Enum.each(["some", "example"], fn x -> IO.puts(x) end)
"some"
"example"
#=> :ok

empty?(enumerable)

Спецификации

empty?(t()) :: boolean()

Определяет, пуст ли enumerable.

Возвращает true, если enumerable пуст, иначе false.

Примеры

iex> Enum.empty?([])
true

iex> Enum.empty?([1, 2, 3])
false

fetch(enumerable, index)

Характеристики

fetch(t(), index()) :: {:ok, element()} | :error

Находит элемент по заданному index (нумерация с нуля).

Возвращает {:ok, element} при нахождении, иначе :error.

Можно передать отрицательный index, что означает, что enumerable перебирается один раз, а index подсчитывается с конца (например, -1 извлекает последний элемент).

Примеры

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

fetch!(enumerable, index)

Характеристики

fetch!(t(), index()) :: element()

Находит элемент по заданному index (нумерация с нуля).

Вызывает OutOfBoundsError если заданное index находится за пределами диапазона enumerable.

Примеры

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

filter(enumerable, fun)

Характеристики

filter(t(), (element() -> as_boolean(term()))) :: list()

Фильтрует enumerable, т.е. возвращает только те элементы, для которых fun возвращает истинное значение.

См. также reject/2, который отбрасывает все элементы, для которых функция возвращает истинное значение.

Примеры

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

Обратите внимание, что filter не может фильтровать и преобразовывать элемент одновременно. Если вам нужно это сделать, воспользуйтесь flat_map/2. Например, если вы хотите преобразовать все строки, представляющие целое число, и отбросить некорректные в одном проходе:

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)

find(enumerable, default \\ nil, fun)

Характеристики

find(t(), default(), (element() -> any())) :: element() | default()

Возвращает первый элемент, для которого fun возвращает истинное значение. Если такой элемент не найден, возвращает default.

Примеры

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

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

find_index(enumerable, fun)

Характеристики

find_index(t(), (element() -> any())) :: non_neg_integer() | nil

Аналогично find/3, но возвращает индекс (нумерация с нуля) элемента вместо самого элемента.

Примеры

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

find_value(enumerable, default \\ nil, fun)

Характеристики

find_value(t(), any(), (element() -> any())) :: any() | nil

Аналогично find/3, но возвращает значение вызова функции вместо самого элемента.

Примеры

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!"

flat_map(enumerable, fun)

Характеристики

flat_map(t(), (element() -> t())) :: list()

Применяет данную fun к enumerable и сплющивает результат.

Эта функция возвращает новый перечислимый набор, полученный путем присоединения результата вызова fun к каждому элементу enumerable вместе; концептуально это аналогично комбинации map/2 и concat/1.

Примеры

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]]

flat_map_reduce(enumerable, acc, fun)

Характеристики

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

Преобразует и сводит enumerable, сплющивая полученные результаты (только один уровень).

Ожидает накопитель и функцию, которая получает каждый элемент перечислимого набора и должна возвращать кортеж, содержащий новый перечислимый набор (часто список) с новым накопителем или кортеж с :halt в качестве первого элемента и накопителем во втором.

Примеры

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}

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

Характеристики

group_by(t(), (element() -> any()), (element() -> any())) :: map()

Разделяет enumerable на группы на основе key_fun.

Результат — это карта, где каждый ключ задаётся key_fun, а каждое значение — список элементов, заданных value_fun . Порядок элементов в каждом списке сохраняется из исходного enumerable. Однако, как и все карты, результирующая карта не упорядочена.

Примеры

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"]}

intersperse(enumerable, element)

Характеристики

intersperse(t(), element()) :: list()

Вставляет element между каждым элементом перечисления.

Примеры

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

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

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

into(enumerable, collectable)

Характеристики

into(Enumerable.t(), Collectable.t()) :: Collectable.t()

Вставляет данный enumerable в collectable.

Обратите внимание, что передача непустого списка в качестве collectable устарела. Если вы собираете в непустой список ключевых слов, рассмотрите использование Keyword.merge/2. Если вы собираете в непустой список, рассмотрите что-то вроде to_list(enumerable) ++ collectable.

Примеры

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}

into(enumerable, collectable, transform)

Характеристики

into(Enumerable.t(), Collectable.t(), (term() -> term())) :: Collectable.t()

Вставляет данный enumerable в collectable в соответствии с функцией преобразования.

Примеры

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}

join(enumerable, joiner \\ "")

Характеристики

join(t(), String.t()) :: String.t()

Объединяет данный enumerable в бинарное значение, используя joiner в качестве разделителя.

Если joiner не указан, он по умолчанию равен пустой строке.

Все элементы в enumerable должны быть преобразуемы в бинарные данные, в противном случае возникает ошибка.

Примеры

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

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

map(enumerable, fun)

Характеристики

map(t(), (element() -> any())) :: list()

Возвращает список, где каждый элемент является результатом вызова fun на каждый соответствующий элемент enumerable.

Для карт функция ожидает кортеж ключ-значение.

Примеры

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]

map_every(enumerable, nth, fun)

Характеристики

map_every(t(), non_neg_integer(), (element() -> any())) :: list()

Возвращает список результатов вызова fun на каждом nth элементе enumerable, начиная с первого элемента.

Первый элемент всегда передаётся в заданную функцию, если nth не равен 0.

Второй аргумент, определяющий каждый nth элемент, должен быть целым неотрицательным числом.

Если nth равен 0, то enumerable напрямую преобразуется в список без применения fun.

Примеры

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]

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

Характеристики

map_join(t(), String.t(), (element() -> String.Chars.t())) :: String.t()

Преобразует и объединяет данный enumerable в одном проходе.

joiner может быть либо бинарным значением, либо списком, а результат будет того же типа, что и joiner. Если joiner не указан, он по умолчанию равен пустой строке.

Все элементы, возвращаемые функцией mapper, должны быть преобразуемы в бинарные данные, в противном случае возникает ошибка.

Примеры

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

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

map_reduce(enumerable, acc, fun)

Характеристики

map_reduce(t(), acc(), (element(), acc() -> {element(), acc()})) ::
  {list(), acc()}

Вызывает заданную функцию для каждого элемента в enumerable для его сведения к одному элементу, сохраняя накопитель.

Возвращает кортеж, где первый элемент — это преобразованный перечислимый набор, а второй — конечный накопитель.

Функция fun получает два аргумента: первый — это элемент, а второй — накопитель. fun должна возвращать кортеж из двух элементов в формате {result, accumulator}.

Для карт первый элемент кортежа должен быть кортежем {key, value}.

Примеры

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

max(перечислимый, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

Характеристики

max(t(), (() -> empty_result)) :: element() | empty_result
when empty_result: any()

Возвращает максимальный элемент в enumerable в соответствии с порядком терминов Erlang.

Если несколько элементов считаются максимальными, возвращается первый найденный.

Вызывает предоставленную empty_fallback функцию и возвращает её значение, если enumerable пусто. По умолчанию empty_fallback вызывает Enum.EmptyError.

Примеры

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

iex> Enum.max([], fn -> 0 end)
0

Тот факт, что эта функция использует порядок терминов Erlang, означает, что сравнение структурное, а не семантическое. Например:

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

В примере выше, max/1 вернул 31 марта, а не 1 апреля, потому что структурное сравнение сравнивает день до года. Это можно исправить, используя max_by/3 и опираясь на структуры, где наиболее значимые цифры идут первыми. В этом конкретном случае мы можем использовать Date.to_erl/1, чтобы получить представление кортежа с полями год, месяц и день:

iex> Enum.max_by([~D[2017-03-31], ~D[2017-04-01]], &Date.to_erl/1)
~D[2017-04-01]

Для выбора максимального значения из двух используйте Kernel.max/2.

max_by(перечислимый, fun, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

Характеристики

max_by(t(), (element() -> any()), (() -> empty_result)) ::
  element() | empty_result
when empty_result: any()

Возвращает максимальный элемент в enumerable, вычисленный с помощью заданной функции.

Если несколько элементов считаются максимальными, возвращается первый найденный.

Вызывает предоставленную empty_fallback функцию и возвращает её значение, если enumerable пусто. По умолчанию empty_fallback вызывает Enum.EmptyError.

Примеры

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"

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

member?(перечислимый, элемент)

Характеристики

member?(t(), element()) :: boolean()

Проверяет, существует ли element в enumerable.

Членство проверяется оператором совпадения (===/2).

Примеры

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

min(перечислимый, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

Характеристики

min(t(), (() -> empty_result)) :: element() | empty_result
when empty_result: any()

Возвращает минимальный элемент в enumerable в соответствии с порядком терминов Erlang.

Если несколько элементов считаются минимальными, возвращается первый найденный.

Вызывает предоставленную empty_fallback функцию и возвращает её значение, если enumerable пусто. По умолчанию empty_fallback вызывает Enum.EmptyError.

Примеры

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

iex> Enum.min([], fn -> 0 end)
0

Тот факт, что эта функция использует порядок терминов Erlang, означает, что сравнение структурное, а не семантическое. Например:

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

В примере выше, min/1 вернул 1 апреля, а не 31 марта, потому что структурное сравнение сравнивает день до года. Это можно исправить, используя min_by/3 и опираясь на структуры, где наиболее значимые цифры идут первыми. В этом конкретном случае мы можем использовать Date.to_erl/1, чтобы получить представление кортежа с полями год, месяц и день:

iex> Enum.min_by([~D[2017-03-31], ~D[2017-04-01]], &Date.to_erl/1)
~D[2017-03-31]

Для выбора минимального значения из двух используйте Kernel.min/2.

min_by(перечислимый, fun, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

Характеристики

min_by(t(), (element() -> any()), (() -> empty_result)) ::
  element() | empty_result
when empty_result: any()

Возвращает минимальный элемент в enumerable, вычисленный с помощью заданной функции.

Если несколько элементов считаются минимальными, возвращается первый найденный.

Вызывает предоставленную empty_fallback функцию и возвращает её значение, если enumerable пусто. По умолчанию empty_fallback вызывает Enum.EmptyError.

Примеры

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"

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

min_max(перечислимый, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

Характеристики

min_max(t(), (() -> empty_result)) :: {element(), element()} | empty_result
when empty_result: any()

Возвращает кортеж с минимальными и максимальными элементами в перечислимом в соответствии с порядком терминов Erlang.

Если несколько элементов считаются максимальными или минимальными, возвращается первый найденный.

Вызывает предоставленную empty_fallback функцию и возвращает её значение, если enumerable пусто. По умолчанию empty_fallback вызывает Enum.EmptyError.

Примеры

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

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

min_max_by(перечислимый, fun, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

Характеристики

min_max_by(t(), (element() -> any()), (() -> empty_result)) ::
  {element(), element()} | empty_result
when empty_result: any()

Возвращает кортеж с минимальными и максимальными элементами в перечислимом, вычисленными с помощью заданной функции.

Если несколько элементов считаются максимальными или минимальными, возвращается первый найденный.

Вызывает предоставленную empty_fallback функцию и возвращает её значение, если enumerable пусто. По умолчанию empty_fallback вызывает Enum.EmptyError.

Примеры

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}

random(перечислимый)

Характеристики

random(t()) :: element()

Возвращает случайный элемент из enumerable.

Вызывает Enum.EmptyError, если enumerable пусто.

Эта функция использует модуль Erlang :rand для расчёта случайного значения. Обратитесь к его документации для установки другого алгоритма случайных чисел или другого начального значения.

Реализация основана на алгоритме выборочного отбора. Предполагается, что возвращаемый образец помещается в память; входной enumerable не обязательно должен быть таким, так как он обрабатывается только один раз.

Если в функцию передаётся диапазон, эта функция выберет случайное значение в пределах пределов диапазона, не перебирая весь диапазон (тем самым выполняется за постоянное время и постоянную память).

Примеры

# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exsplus, {101, 102, 103})
iex> Enum.random([1, 2, 3])
2
iex> Enum.random([1, 2, 3])
1
iex> Enum.random(1..1_000)
776

reduce(перечислимый, fun)

Характеристики

reduce(t(), (element(), acc() -> acc())) :: acc()

Вызывает fun для каждого элемента в enumerable с накопителем.

Вызывает Enum.EmptyError, если enumerable пусто.

Первый элемент enumerable используется в качестве начального значения накопителя. Затем функция вызывается с последующим элементом и накопителем. Результат, возвращённый функцией, используется в качестве накопителя для следующей итерации, рекурсивно. После завершения enumerable возвращается последний накопитель.

Поскольку первый элемент перечислимого используется в качестве начального значения накопителя, fun будет выполняться n - 1 раз, где n — длина перечислимого. Эта функция не вызовет указанную функцию для перечислимых элементов длиной один элемент.

Если вы хотите использовать другое значение для накопителя, используйте Enum.reduce/3.

Примеры

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

reduce(перечислимый, acc, fun)

Характеристики

reduce(t(), any(), (element(), any() -> any())) :: any()

Вызывает fun для каждого элемента в enumerable с накопителем.

Начальное значение накопителя — acc. Функция вызывается для каждого элемента в перечислимом с накопителем. Результат, возвращённый функцией, используется в качестве накопителя для следующей итерации. Функция возвращает последний накопитель.

Примеры

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

Reduce как строительный блок

Reduce (иногда называемый fold) является основным строительным блоком в функциональном программировании. Почти все функции в модуле Enum могут быть реализованы на основе reduce. Эти функции часто полагаются на другие операции, такие как Enum.reverse/1, которые оптимизированы во время выполнения.

Например, мы могли бы реализовать map/2 в терминах reduce/3 следующим образом:

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

В примере выше, Enum.reduce/3 накапливает результат каждого вызова fun в список в обратном порядке, который корректно упорядочивается в конце вызовом Enum.reverse/1.

Реализация функций, таких как map/2, filter/2 и других, является хорошим упражнением для понимания возможностей Enum.reduce/3. Когда операция не может быть выражена ни одной из функций в модуле Enum, разработчики, скорее всего, прибегнут к reduce/3.

reduce_while(enumerable, acc, fun)

Характеристики

reduce_while(t(), any(), (element(), any() -> {:cont, any()} | {:halt, any()})) ::
  any()

Редуцирует enumerable до тех пор, пока fun не вернёт {:halt, term}.

Значение возвращаемое fun ожидается

  • {:cont, acc} для продолжения редукции с acc в качестве нового аккумулятора или
  • {:halt, acc} для остановки редукции

Если fun возвращает {:halt, acc} , редукция останавливается, и функция возвращает acc. В противном случае, если перечисляемый объект исчерпан, функция возвращает аккумулятор последнего {:cont, acc}.

Примеры

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

reject(enumerable, fun)

Характеристики

reject(t(), (element() -> as_boolean(term()))) :: list()

Возвращает список элементов в enumerable , исключая те, для которых функция fun возвращает истинное значение.

См. также filter/2.

Примеры

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

reverse(enumerable)

Характеристики

reverse(t()) :: list()

Возвращает список элементов в enumerable в обратном порядке.

Примеры

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

reverse(enumerable, tail)

Характеристики

reverse(t(), t()) :: list()

Инвертирует элементы в enumerable, добавляет tail, и возвращает его как список.

Это оптимизация для enumerable |> Enum.reverse() |> Enum.concat(tail).

Примеры

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

reverse_slice(enumerable, start_index, count)

Характеристики

reverse_slice(t(), non_neg_integer(), non_neg_integer()) :: list()

Инвертирует enumerable в диапазоне от начального start_index до count элементов.

Если count больше размера остальной части enumerable, эта функция инвертирует остальную часть перечисляемого объекта.

Примеры

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

scan(enumerable, fun)

Характеристики

scan(t(), (element(), any() -> any())) :: list()

Применяет заданную функцию к каждому элементу в enumerable, сохраняя результат в списке и передавая его в качестве аккумулятора для следующего вычисления. Использует первый элемент в enumerable в качестве начального значения.

Примеры

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

scan(enumerable, acc, fun)

Характеристики

scan(t(), any(), (element(), any() -> any())) :: list()

Применяет заданную функцию к каждому элементу в enumerable, сохраняя результат в списке и передавая его в качестве аккумулятора для следующего вычисления. Использует заданное acc в качестве начального значения.

Примеры

iex> Enum.scan(1..5, 0, &(&1 + &2))
[1, 3, 6, 10, 15]

shuffle(enumerable)

Характеристики

shuffle(t()) :: list()

Возвращает список с перемешанными элементами enumerable.

Эта функция использует модуль Erlang's :rand модуль для вычисления случайного значения. Обратитесь к его документации для настройки другого алгоритма генерации случайных чисел или другого значения семени.

Примеры

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

slice(enumerable, index_range)

Характеристики

slice(t(), Range.t()) :: list()

Возвращает подмножество списка заданного enumerable с помощью index_range.

index_range должен быть Range. При заданном enumerable, он отбрасывает элементы до index_range.first (нумерация с нуля), а затем берет элементы до элемента index_range.last (включительно).

Индексы нормализованы, то есть отрицательные индексы будут считаться от конца (например, -1 означает последний элемент enumerable).

Если index_range.last находится вне границ, то ему присваивается индекс последнего элемента.

Если нормализованный index_range.first находится вне границ заданного enumerable, или этот index_range.last больше нормализованного index_range.last, тогда возвращается [].

Примеры

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)
[]

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

slice(enumerable, start_index, amount)

Характеристики

slice(t(), index(), non_neg_integer()) :: list()

Возвращает подмножество списка заданного enumerable, начиная с start_index (нумерация с нуля) с amount количеством элементов, если они доступны.

При заданном enumerable, он пропускает элементы перед элементом start_index, затем берет amount элементов, возвращая как можно больше элементов, если их недостаточно.

Можно передать отрицательный start_index, что означает, что enumerable перечисляется один раз, а индекс подсчитывается с конца (например, -1 начинает срез с последнего элемента).

Возвращает [] , если amount равен 0 или если start_index выходит за пределы границ.

Примеры

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)
[]

sort(enumerable)

Характеристики

sort(t()) :: list()

Сортирует enumerable в соответствии с порядком Эрланга.

Использует алгоритм слияния.

Примеры

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

sort(enumerable, fun)

Характеристики

sort(t(), (element(), element() -> boolean())) :: list()

Сортирует enumerable с помощью заданной функции.

Эта функция использует алгоритм слияния. Заданная функция должна сравнивать два аргумента и возвращать true , если первый аргумент предшествует второму.

Примеры

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

Алгоритм сортировки будет стабильным, если заданная функция возвращает true для значений, считающихся равными:

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

Если функция не возвращает true для равных значений, сортировка не является стабильной, и порядок равных элементов может быть изменён. Например:

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

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

Характеристики

sort_by(
  t(),
  (element() -> mapped_element),
  (mapped_element, mapped_element -> boolean())
) :: list()
when mapped_element: element()

Сортирует результаты отображения enumerable в соответствии с предоставленной функцией sorter.

Эта функция отображает каждый элемент enumerable с помощью предоставленной функции mapper . Затем перечисляемый объект сортируется по отображенным элементам с использованием функции sorter , которая по умолчанию равна Kernel.<=/2.

sort_by/3 отличается от sort/2 тем, что вычисляет значение сравнения для каждого элемента в перечисляемом объекте только один раз, а не один раз для каждого элемента в каждом сравнении. Если одна и та же функция вызывается для обоих элементов, то использование sort_by/3 также более компактно.

Примеры

Использование по умолчанию sorter <=/2:

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

Использование пользовательской функции sorter для переопределения порядка:

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

Сортировка по нескольким свойствам — сначала по размеру, затем по первой букве (это использует тот факт, что кортежи сравниваются по элементу):

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

split(enumerable, count)

Характеристики

split(t(), integer()) :: {list(), list()}

Разделяет enumerable на два перечисляемых объекта, оставляя count элементов в первом.

Если count отрицательное число, оно начинается с подсчёта с конца к началу enumerable.

Обратите внимание, что отрицательное count подразумевает, что enumerable будет перечисляться дважды: один раз для вычисления позиции и второй раз для фактического разделения.

Примеры

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]}

split_while(enumerable, fun)

Характеристики

split_while(t(), (element() -> as_boolean(term()))) :: {list(), list()}

Разделяет перечисляемый объект на две части в позиции элемента, для которого fun возвращает ложное значение (false или nil) в первый раз.

Возвращает кортеж из двух элементов с двумя списками элементов. Элемент, вызвавший разделение, является частью второго списка.

Примеры

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], []}

split_with(enumerable, fun)

Характеристики

split_with(t(), (element() -> as_boolean(term()))) :: {list(), list()}

Разделяет enumerable на две списка в соответствии с заданной функцией fun.

Разделяет заданный enumerable на два списка, вызывая fun с каждым элементом в enumerable в качестве единственного аргумента. Возвращает кортеж с первым списком, содержащим все элементы в enumerable, для которых применение fun вернуло истинное значение, и вторым списком со всеми элементами, для которых применение fun вернуло ложное значение (false или nil).

Элементы в обоих возвращаемых списках расположены в том же относительном порядке, что и в исходном перечислимом (если такой перечислимый был упорядочен, например, список). См. примеры ниже.

Примеры

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)
{[], []}

sum(enumerable)

Характеристики

sum(t()) :: number()

Возвращает сумму всех элементов.

Вызывает исключение ArithmeticError, если enumerable содержит нечисловое значение.

Примеры

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

take(enumerable, amount)

Характеристики

take(t(), integer()) :: list()

Извлекает amount элементов с начала или конца enumerable.

Если задано положительное amount, оно извлекает amount элементов с начала enumerable.

Если задано отрицательное amount, будут извлечены amount элементов с конца. enumerable будет перечислен один раз для получения правильного индекса, а оставшееся вычисление выполняется с конца.

Если значение amount является 0, оно возвращает [].

Примеры

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]

take_every(enumerable, nth)

Характеристики

take_every(t(), non_neg_integer()) :: list()

Возвращает список каждого nth элемента в enumerable, начиная с первого элемента.

Первый элемент всегда включается, если только nth не равен 0.

Второй аргумент, определяющий каждый nth элемент, должен быть неотрицательным целым числом.

Примеры

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]

take_random(enumerable, count)

Характеристики

take_random(t(), non_neg_integer()) :: list()

Извлекает count случайных элементов из enumerable.

Обратите внимание, что эта функция будет перебирать весь enumerable для получения случайного подсписка.

См. random/1 для заметок об реализации и случайном зерне.

Примеры

# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exsplus, {1, 2, 3})
iex> Enum.take_random(1..10, 2)
[5, 4]
iex> Enum.take_random(?a..?z, 5)
'ipybz'

take_while(enumerable, fun)

Характеристики

take_while(t(), (element() -> as_boolean(term()))) :: list()

Извлекает элементы с начала enumerable до тех пор, пока fun возвращает истинное значение.

Примеры

iex> Enum.take_while([1, 2, 3], fn x -> x < 3 end)
[1, 2]

to_list(enumerable)

Характеристики

to_list(t()) :: [element()]

Преобразует enumerable в список.

Примеры

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

uniq(enumerable)

Характеристики

uniq(t()) :: list()

Перечисляет enumerable, удаляя все дублирующиеся элементы.

Примеры

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

uniq_by(enumerable, fun)

Характеристики

uniq_by(t(), (element() -> term())) :: list()

Перечисляет enumerable, удаляя элементы, для которых функция fun возвращает дублирующиеся элементы.

Функция fun сопоставляет каждый элемент с термином. Два элемента считаются дубликатами, если возвращаемое значение fun одинаково для обоих.

Сохраняется первое вхождение каждого элемента.

Пример

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}]

unzip(enumerable)

Характеристики

unzip(t()) :: {[element()], [element()]}

Обратная функция к zip/2. Извлекает кортежи из двух элементов из заданного enumerable и группирует их вместе.

Принимает enumerable с элементами, являющимися кортежами из точно двух элементов, и возвращает кортеж с двумя списками, каждый из которых сформирован из первого и второго элемента каждого кортежа соответственно.

Эта функция терпит неудачу, если enumerable не является или не может быть преобразована в список кортежей с точно двумя элементами в каждом кортеже.

Примеры

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]}

with_index(enumerable, offset \\ 0)

Характеристики

with_index(t(), integer()) :: [{element(), index()}]

Возвращает enumerable с каждым элементом, заключенным в кортеж вместе с его индексом.

Если задан offset, мы будем индексировать с заданного смещения вместо нуля.

Примеры

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]

zip(enumerables)

Характеристики

zip(enumerables) :: [tuple()] when enumerables: [t()] | t()

Объединяет соответствующие элементы из конечного набора перечислимых объектов в один список кортежей.

Объединение завершается, как только какой-либо перечислимый объект в заданном наборе завершается.

Примеры

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}]

zip(enumerable1, enumerable2)

Характеристики

zip(t(), t()) :: [{any(), any()}]

Объединяет соответствующие элементы из двух перечислимых объектов в один список кортежей.

Объединение завершается, как только любой перечислимый объект завершается.

Примеры

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}]

© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.9.4/Enum.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API