Spec-Zone.ru › Elixir 1.14

Enum

Функции для работы со структурами данных (известными как перечислимые).

В 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)

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

all?(enumerable, fun)

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

any?(enumerable)

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

any?(enumerable, fun)

Возвращает 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 возвращает истинное значение.

count_until(enumerable, limit)

Считает перечислимый объект, останавливаясь на limit.

count_until(enumerable, fun, limit)

Считает элементы в перечислимом объекте, для которых fun возвращает истинное значение, останавливаясь на limit.

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)

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

frequencies(enumerable)

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

frequencies_by(enumerable, key_fun)

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

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

Разбивает enumerable на группы на основе key_fun.

intersperse(enumerable, separator)

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

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_intersperse(enumerable, separator, mapper)

Применяет отображение и вставляет разделитель для данного перечислимого объекта за один проход.

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

Применяет отображение и объединяет данный перечислимый объект за один проход.

map_reduce(enumerable, acc, fun)

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

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

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

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

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

member?(enumerable, element)

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

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

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

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

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

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

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

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

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

product(enumerable)

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

random(enumerable)

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

reduce(enumerable, fun)

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

reduce(enumerable, acc, fun)

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

reduce_while(enumerable, acc, fun)

Сокращает enumerable до тех пор, пока fun не вернёт {:halt, term}.

reject(enumerable, fun)

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

reverse(enumerable)

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

reverse(enumerable, tail)

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

reverse_slice(enumerable, start_index, count)

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

scan(enumerable, fun)

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

scan(enumerable, acc, fun)

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

shuffle(enumerable)

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

slice(enumerable, index_range)

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

slice(enumerable, start_index, amount)

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

slide(enumerable, range_or_single_index, insertion_index)

Перемещает один или несколько элементов, заданных range_or_single_index от enumerable к insertion_index.

sort(enumerable)

Сортирует enumerable в соответствии с порядком Erlang.

sort(enumerable, sorter)

Сортирует enumerable по заданной функции.

sort_by(enumerable, mapper, sorter \\ :asc)

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

split(enumerable, count)

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

split_while(enumerable, fun)

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

split_with(enumerable, fun)

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

sum(enumerable)

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

take(enumerable, amount)

Берёт amount элементов с начала или конца enumerable.

take_every(enumerable, nth)

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

take_random(enumerable, count)

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

take_while(enumerable, fun)

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

to_list(enumerable)

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

uniq(enumerable)

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

uniq_by(enumerable, fun)

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

unzip(list)

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

with_index(enumerable, fun_or_offset \\ 0)

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

zip(enumerables)

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

zip(enumerable1, enumerable2)

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

zip_reduce(enums, acc, reducer)

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

zip_reduce(left, right, acc, reducer)

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

zip_with(enumerables, zip_fun)

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

zip_with(enumerable1, enumerable2, zip_fun)

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

Типы

acc()Source

@type acc() :: any()

default()Source

@type default() :: any()

element()Source

@type element() :: any()

index()Source

@type index() :: integer()

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

t()Source

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

Функции

all?(перечисляемый)Источник

@spec all?(t()) :: boolean()

Возвращает true, если все элементы в enumerable истинны.

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

Примеры

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

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

iex> Enum.all?([])
true

all?(перечисляемый, функция)Источник

@spec 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 _ -> nil end)
true

Как показывает последний пример, Enum.all?/2 возвращает true, если enumerable пусто, независимо от fun. В пустом перечисляемом нет элемента, для которого fun возвращает ложное значение, поэтому результат должен быть true. Это хорошо определённое логическое утверждение для пустых коллекций.

any?(перечисляемый)Источник

@spec any?(t()) :: boolean()

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

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

Примеры

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

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

iex> Enum.any?([])
false

any?(перечисляемый, функция)Источник

@spec 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

at(перечисляемый, индекс, значение_по_умолчанию \\ nil)Источник

@spec 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(перечисляемый, функция)Источник

@spec 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(перечисляемый, количество)Источник

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

Является сокращением для chunk_every(enumerable, count, count).

chunk_every(перечисляемый, количество, шаг, остаток \\ [])Источник

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

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

chunk_while(перечисляемый, накопитель, функция_фрагмента, функция_после)Источник

@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()

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

chunk_fun получает текущий элемент и накопитель и должен вернуть:

  • {:cont, chunk, acc} для вывода фрагмента и продолжения с накопителем
  • {:cont, acc} для того, чтобы не выводить фрагмент и продолжить с накопителем
  • {:halt, acc} для прекращения разбиения перечисляемого объекта.

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

  • {:cont, chunk, acc} для вывода фрагмента. Фрагмент будет добавлен в список уже выведенных фрагментов.
  • {:cont, acc} для того, чтобы не выводить фрагмент

Накопитель в after_fun необходим для отражения формата кортежа из chunk_fun, но он будет отброшен, поскольку обход завершён.

Возвращает список выведенных фрагментов.

Примеры

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]]
iex> Enum.chunk_while([1, 2, 3, 5, 7], [], chunk_fun, after_fun)
[[1, 2], [3, 5, 7]]

concat(перечисляемые)Источник

@spec 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(левый, правый)Источник

@spec concat(t(), t()) :: t()

Конкатенирует перечисляемый в right с перечисляемым в left.

Эта функция производит тот же результат, что и оператор ++/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(перечисляемый)Источник

@spec count(t()) :: non_neg_integer()

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

Примеры

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

count(перечисляемый, функция)Источник

@spec 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

count_until(перечисляемый, лимит)Источник

@spec count_until(t(), pos_integer()) :: non_neg_integer()

Считает перечисляемый объект, останавливаясь на limit.

Это полезно для проверки определённых свойств счётчика перечисляемого объекта, без необходимости подсчёта всего перечисляемого объекта. Например, если вы хотите проверить, что счётчик равен, не меньше или больше значения.

Если перечисляемый объект реализует Enumerable.count/1, перечисляемый объект не перебирается, и мы возвращаем меньшее из двух чисел. Чтобы принудительно выполнить перебор, используйте count_until/3 с fn _ -> true end в качестве второго аргумента.

Примеры

iex> Enum.count_until(1..20, 5)
5
iex> Enum.count_until(1..20, 50)
20
iex> Enum.count_until(1..10, 10) == 10 # At least 10
true
iex> Enum.count_until(1..11, 10 + 1) > 10 # More than 10
true
iex> Enum.count_until(1..5, 10) < 10 # Less than 10
true
iex> Enum.count_until(1..10, 10 + 1) == 10 # Exactly ten
true
END_OF_DOCUMENT_MARKER

count_until(enumerable, fun, limit)Source

@spec count_until(t(), (element() -> as_boolean(term())), pos_integer()) ::
  non_neg_integer()

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

См. count/2 и count_until/3 для получения дополнительной информации.

Примеры

iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 7)
7
iex> Enum.count_until(1..20, fn x -> rem(x, 2) == 0 end, 11)
10

dedup(enumerable)Source

@spec 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)Source

@spec 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)Source

@spec 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)Source

@spec 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)Source

@spec 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)Source

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

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

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

Примеры

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

empty?(enumerable)Source

@spec empty?(t()) :: boolean()

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

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

Примеры

iex> Enum.empty?([])
true

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

fetch(enumerable, index)Source

@spec 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)Source

@spec 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)Source

@spec 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)Source

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

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

Примеры

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

find_index(enumerable, fun)Source

@spec 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)Source

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

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

Возвращаемое значение считается найденным, когда результат истинно (ни nil ни false).

Примеры

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

flat_map(enumerable, fun)Source

@spec 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)Source

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

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

Ожидается аккумулирующая переменная и функция, принимающая каждый элемент перечисляемого объекта и возвращающая кортеж, содержащий новый перечисляемый объект (часто список) с новой аккумулирующей переменной или кортеж с :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}

frequencies(enumerable)Source

@spec frequencies(t()) :: map()

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

Примеры

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

frequencies_by(enumerable, key_fun)Source

@spec frequencies_by(t(), (element() -> any())) :: map()

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

Примеры

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}

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

@spec 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, separator)Source

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

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

Примеры

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)Source

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

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

Обратите внимание, что передача непустого списка в качестве collectable устарела. Если вы собираете в непустой именованный список, рассмотрите возможность использования Keyword.merge(collectable, Enum.to_list(enumerable)). Если вы собираете в непустой список, рассмотрите что-то вроде Enum.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)Source

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

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

Примеры

iex> Enum.into([1, 2, 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 \\ "")Source

@spec 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"

iex> Enum.join([["a", "b"], ["c", "d", "e", ["f", "g"]], "h", "i"], " ")
"ab cdefg h i"

map(enumerable, fun)Source

@spec 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)Source

@spec 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_intersperse(enumerable, separator, mapper)Source

@spec map_intersperse(t(), element(), (element() -> any())) :: list()

Отображает и вставляет заданное перечисление за один проход.

Примеры

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

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

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

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

Если 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)Source

@spec 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(enumerable, sorter \\ &>=/2, empty_fallback \\ fn -> raise Enum.EmptyError end)Source

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

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

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

Если перечисление пусто, вызывается предоставленный empty_fallback. empty_fallback по умолчанию вызывает Enum.EmptyError.

Примеры

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

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

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

В приведенном выше примере max/2 вернул 31 марта вместо 1 апреля, потому что структурное сравнение сравнивает день до года. По этой причине большинство структур предоставляют функцию «сравнения», такую как Date.compare/2, которая принимает две структуры и возвращает :lt (меньше чем), :eq (равно) и :gt (больше чем). Если вы передадите модуль в качестве функции сортировки, Elixir автоматически будет использовать функцию compare/2 этого модуля:

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

Наконец, если вы не хотите вызывать исключение при пустых перечислениях, вы можете передать функцию обработки пустого множества:

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

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

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

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

По умолчанию сравнение выполняется с помощью функции-сортировщика >=. Если несколько элементов считаются максимальными, возвращается первый найденный. Если нужно вернуть последний элемент, считающийся максимальным, функция-сортировщик не должна возвращать true для равных элементов.

Вызывает предоставленную 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"

Тот факт, что эта функция использует эрланговый порядок терминов, означает, что сравнение является структурным, а не семантическим. Поэтому, если нужно сравнивать структуры, большинство структур предоставляют функцию "compare", такую как Date.compare/2, которая получает две структуры и возвращает :lt (меньше), :eq (равно) и :gt (больше). Если вы передадите модуль в качестве функции сортировки, Elixir автоматически будет использовать функцию compare/2 указанного модуля:

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

Наконец, если вы не хотите вызывать исключение при работе с пустыми перечислениями, вы можете передать обратный вызов для пустого случая:

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

member?(enumerable, element)Source

@spec 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

При вызове вне защитных блоков операторы in и not in работают, используя эту функцию.

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

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

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

По умолчанию сравнение выполняется с помощью функции-сортировщика <=. Если несколько элементов считаются минимальными, возвращается первый найденный. Если нужно вернуть последний элемент, считающийся минимальным, функция-сортировщик не должна возвращать true для равных элементов.

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

Примеры

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

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

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

В примере выше, min/2 вернула 1 апреля вместо 31 марта, потому что структурное сравнение сравнивает день до года. По этой причине большинство структур предоставляют функцию "compare", такую как Date.compare/2, которая получает две структуры и возвращает :lt (меньше), :eq (равно) и :gt (больше). Если вы передадите модуль в качестве функции сортировки, Elixir автоматически будет использовать функцию compare/2 указанного модуля:

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

Наконец, если вы не хотите вызывать исключение при работе с пустыми перечислениями, вы можете передать обратный вызов для пустого случая:

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

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

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

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

По умолчанию сравнение выполняется с помощью функции-сортировщика <=. Если несколько элементов считаются минимальными, возвращается первый найденный. Если нужно вернуть последний элемент, считающийся минимальным, функция-сортировщик не должна возвращать true для равных элементов.

Вызывает предоставленную 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"

Тот факт, что эта функция использует эрланговый порядок терминов, означает, что сравнение является структурным, а не семантическим. Поэтому, если нужно сравнивать структуры, большинство структур предоставляют функцию "compare", такую как Date.compare/2, которая получает две структуры и возвращает :lt (меньше), :eq (равно) и :gt (больше). Если вы передадите модуль в качестве функции сортировки, Elixir автоматически будет использовать функцию compare/2 указанного модуля:

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

Наконец, если вы не хотите вызывать исключение при работе с пустыми перечислениями, вы можете передать обратный вызов для пустого случая:

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

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

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

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

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

Вызывает предоставленную 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(enumerable, fun, sorter_or_empty_fallback \\ &</2, empty_fallback \\ fn -> raise Enum.EmptyError end)Source

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

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

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

Примеры

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}

Тот факт, что эта функция использует эрланговый порядок терминов, означает, что сравнение является структурным, а не семантическим. Поэтому, если нужно сравнивать структуры, большинство структур предоставляют функцию "compare", такую как Date.compare/2, которая получает две структуры и возвращает :lt (меньше), :eq (равно) и :gt (больше). Если вы передадите модуль в качестве функции сортировки, Elixir автоматически будет использовать функцию compare/2 указанного модуля:

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

Наконец, если вы не хотите вызывать исключение при работе с пустыми перечислениями, вы можете передать обратный вызов для пустого случая:

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

product(enumerable)Source

@spec product(t()) :: number()

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

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

Примеры

iex> Enum.product([])
1
iex> Enum.product([2, 3, 4])
24
iex> Enum.product([2.0, 3.0, 4.0])
24.0

random(enumerable)Source

@spec random(t()) :: element()

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

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

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

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

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

Примеры

В примерах ниже используется псевдослучайный алгоритм :exsss, так как он является значением по умолчанию из Erlang/OTP 22:

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

reduce(enumerable, fun)Source

@spec 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(enumerable, acc, fun)Source

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

Вызывает 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)Source

@spec 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)Source

@spec 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)Source

@spec reverse(t()) :: list()

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

Примеры

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

reverse(enumerable, tail)Source

@spec 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)Source

@spec 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)Source

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

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

Примеры

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

scan(enumerable, acc, fun)Source

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

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

Примеры

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

shuffle(enumerable)Source

@spec shuffle(t()) :: list()

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

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

Примеры

В примерах ниже используется псевдослучайный алгоритм :exsss поскольку он является значением по умолчанию в Erlang/OTP 22:

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

slice(enumerable, index_range)Source

@spec 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, возвращается [].

Если используется шаг n (отличный от 1) в index_range, он берет каждый n-й элемент от index_range.first до index_range.last (согласно тем же правилам, описанным выше).

Примеры

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

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

# Last three elements (negative indexes)
iex> Enum.slice([1, 2, 3, 4, 5], -3..-1)
[3, 4, 5]

Для диапазонов, где start > stop, необходимо явно указать их как возрастающие:

iex> Enum.slice([1, 2, 3, 4, 5], 1..-2//1)
[2, 3, 4]

Шаг может быть любым положительным числом. Например, для получения каждого 2-го элемента коллекции:

iex> Enum.slice([1, 2, 3, 4, 5], 0..-1//2)
[1, 3, 5]

Для получения каждого третьего элемента первых десяти элементов:

iex> integers = Enum.to_list(1..20)
iex> Enum.slice(integers, 0..9//3)
[1, 4, 7, 10]

Если первая позиция находится после конца перечисляемого или после последней позиции диапазона, возвращается пустой список:

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

# first is greater than last
iex> Enum.slice([1, 2, 3, 4, 5], 6..5)
[]

slice(enumerable, start_index, amount)Source

@spec 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]
iex> Enum.slice(1..10, -11, 5)
[1, 2, 3, 4, 5]

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

slide(enumerable, range_or_single_index, insertion_index)Source

@spec slide(t(), Range.t() | index(), index()) :: list()

Сдвигает один или несколько элементов, заданных range_or_single_index с enumerable до insertion_index.

Семантика перемещаемого диапазона соответствует семантике Enum.slice/2. В частности, это означает:

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

  • Если нормализованный диапазон индексов last выходит за пределы, диапазон усекается до последнего элемента.

  • Если нормализованный диапазон индексов first выходит за пределы, выбранный диапазон для сдвига будет пустым, поэтому вы получите исходный список.

  • Убывающие диапазоны (например, 5..0//1) также выбирают пустой диапазон для перемещения, поэтому вы получите исходный список.

  • Диапазоны с любым шагом, кроме 1, приведут к ошибке.

Примеры

# Slide a single element
iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 5, 1)
[:a, :f, :b, :c, :d, :e, :g]

# Slide a range of elements backward
iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..5, 1)
[:a, :d, :e, :f, :b, :c, :g]

# Slide a range of elements forward
iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 1..3, 5)
[:a, :e, :f, :b, :c, :d, :g]

# Slide with negative indices (counting from the end)
iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3..-1//1, 2)
[:a, :b, :d, :e, :f, :g, :c]
iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], -4..-2, 1)
[:a, :d, :e, :f, :b, :c, :g]

# Insert at negative indices (counting from the end)
iex> Enum.slide([:a, :b, :c, :d, :e, :f, :g], 3, -1)
[:a, :b, :c, :e, :f, :g, :d]

sort(enumerable)Source

@spec sort(t()) :: list()

Сортирует enumerable в соответствии с порядком Erlang.

Эта функция использует алгоритм слияния. Не используйте эту функцию для сортировки структур, см. sort/2 для получения дополнительной информации.

Примеры

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

sort(enumerable, sorter)Source

@spec sort(
  t(),
  (element(), element() -> boolean())
  | :asc
  | :desc
  | module()
  | {:asc | :desc, module()}
) :: 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"]

Возрастание и убывание (с версии v1.10.0)

sort/2 позволяет разработчику передавать :asc или :desc в качестве сортировщика, что является удобством для &<=/2 и &>=/2 соответственно.

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

Сортировка структур

Не используйте </2, <=/2, >/2, >=/2 и им подобные при сортировке структур. Это связано с тем, что встроенные операторы выше выполняют структурное сравнение, а не семантическое. Представьте, что мы сортируем следующий список дат:

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

Обратите внимание, что возвращаемый результат неверен, потому что sort/1 по умолчанию использует <=/2, которое будет сравнивать их структуру. При сравнении структур поля сравниваются в алфавитном порядке, что означает, что указанные выше даты будут сравниваться по day, month и затем year, что является противоположным тому, что мы хотим.

По этой причине большинство структур предоставляют функцию «сравнения», такую как Date.compare/2, которая получает две структуры и возвращает :lt (меньше), :eq (равно) и :gt (больше). Если вы передадите модуль как функцию сортировки, Elixir автоматически будет использовать функцию compare/2 указанного модуля:

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

Чтобы получить все даты в порядке убывания, вы можете обернуть модуль в кортеж с :asc или :desc в качестве первого элемента:

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

sort_by(enumerable, mapper, sorter \\ :asc)Source

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

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

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

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

Возрастание и убывание (с версии v1.10.0)

sort_by/3 позволяет разработчику передавать :asc или :desc в качестве сортировщика, что является удобством для &<=/2 и &>=/2 соответственно:

iex> Enum.sort_by([2, 3, 1], &(&1), :asc)
[1, 2, 3]

iex> Enum.sort_by([2, 3, 1], &(&1), :desc)
[3, 2, 1]

Примеры

Используя значение по умолчанию sorter :asc:

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

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

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

Аналогично sort/2, вы можете передать пользовательскую функцию сортировки:

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

Как и в sort/2, избегайте использования функции сортировки по умолчанию для сортировки структур, так как по умолчанию она выполняет структурное сравнение вместо семантического. В таких случаях вы должны передать функцию сортировки как третий элемент или любой модуль, который реализует функцию compare/2. Например, для сортировки пользователей по дате рождения в порядке возрастания и убывания соответственно:

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

Характеристики производительности

Как подробно описано в первом разделе, sort_by/3 вычисляет значение сравнения для каждого элемента в перечислимом списке один раз вместо одного раза для каждого элемента в каждом сравнении. Это подразумевает, что sort_by/3 должен выполнить начальный проход по данным для вычисления этих значений.

Однако, если эти значения легко вычислить, например, вы уже извлекли нужное поле для сортировки в кортеж, то эти дополнительные проходы становятся издержками. В таких случаях рассмотрите использование List.keysort/3 вместо этого.

Давайте посмотрим пример. Представьте, что у вас есть список продуктов и список идентификаторов. Вы хотите сохранить все продукты, которые есть в заданных идентификаторах, и вернуть их названия, отсортированные по цене. Вы могли бы написать это так:

for(
  product <- products,
  product.id in ids,
  do: product
)
|> Enum.sort_by(& &1.price)
|> Enum.map(& &1.name)

Однако, вы также можете написать это так:

for(
  product <- products,
  product.id in ids,
  do: {product.name, product.price}
)
|> List.keysort(1)
|> Enum.map(&elem(&1, 0))

Использование List.keysort/3 будет лучшим выбором для производительности, так как оно избегает дополнительных проходов.

split(enumerable, count)Source

@spec 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)Source

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

Разделяет enumerable на две части в позиции элемента, для которого 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)Source

@spec 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)Source

@spec sum(t()) :: number()

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

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

Примеры

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

iex> Enum.sum(1..10)
55

iex> Enum.sum(1..10//2)
25

take(enumerable, amount)Source

@spec 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)Source

@spec 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)Source

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

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

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

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

Примеры

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

take_while(enumerable, fun)Source

@spec 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)Source

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

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

Примеры

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

uniq(enumerable)Source

@spec uniq(t()) :: list()

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

Примеры

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

uniq_by(enumerable, fun)Source

@spec 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(list)Source

@spec 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, fun_or_offset \\ 0)Source

@spec with_index(t(), integer()) :: [{term(), integer()}]
@spec with_index(t(), (element(), index() -> value)) :: [value] when value: any()

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

Может принимать функцию или целочисленный сдвиг.

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

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

Примеры

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]

iex> Enum.with_index([:a, :b, :c], fn element, index -> {index, element} end)
[{0, :a}, {1, :b}, {2, :c}]

zip(enumerables)Source

@spec 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)Source

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

zip_reduce(enums, acc, reducer)Source

@spec zip_reduce(t(), acc, ([term()], acc -> acc)) :: acc when acc: term()

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

Редуктор будет получать 2 аргумента: список элементов (по одному из каждого перечислимого) и накопитель.

На практике поведение, предоставляемое этой функцией, может быть достигнуто с помощью:

Enum.reduce(Stream.zip(enums), acc, reducer)

Но zip_reduce/3 существует для удобства.

Примеры

iex> enums = [[1, 1], [2, 2], [3, 3]]
...>  Enum.zip_reduce(enums, [], fn elements, acc ->
...>    [List.to_tuple(elements) | acc]
...> end)
[{1, 2, 3}, {1, 2, 3}]

iex> enums = [[1, 2], %{a: 3, b: 4}, [5, 6]]
...> Enum.zip_reduce(enums, [], fn elements, acc ->
...>   [List.to_tuple(elements) | acc]
...> end)
[{2, {:b, 4}, 6}, {1, {:a, 3}, 5}]

zip_reduce(left, right, acc, reducer)Source

@spec zip_reduce(
  t(),
  t(),
  acc,
  (enum1_elem :: term(), enum2_elem :: term(), acc -> acc)
) :: acc
when acc: term()

Выполняет редукцию по двум перечислимым, останавливаясь, как только любой из перечислимых оказывается пустым.

На практике поведение, предоставляемое этой функцией, может быть достигнуто с помощью:

Enum.reduce(Stream.zip(left, right), acc, reducer)

Но zip_reduce/4 существует для удобства.

Примеры

iex> Enum.zip_reduce([1, 2], [3, 4], 0, fn x, y, acc -> x + y + acc end)
10

iex> Enum.zip_reduce([1, 2], [3, 4], [], fn x, y, acc -> [x + y | acc] end)
[6, 4]

zip_with(enumerables, zip_fun)Source

@spec zip_with(t(), ([term()] -> term())) :: [term()]

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

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

Возвращает список со всеми результатами вызова функции zip_fun.

Примеры

iex> Enum.zip_with([[1, 2], [3, 4], [5, 6]], fn [x, y, z] -> x + y + z end)
[9, 12]

iex> Enum.zip_with([[1, 2], [3, 4]], fn [x, y] -> x + y end)
[4, 6]

zip_with(enumerable1, enumerable2, zip_fun)Source

@spec zip_with(t(), t(), (enum1_elem :: term(), enum2_elem :: term() -> term())) :: [
  term()
]

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

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

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

Объединение словарей

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

left =  %{:a => 1, 1 => 3}
right = %{:a => 1, :b => :c}
Enum.zip(left, right)
# [{{1, 3}, {:a, 1}}, {{:a, 1}, {:b, :c}}]

Как видите, :a не соединяется с :a. Если это то, что вам нужно, вы должны использовать Map.merge/3.

Примеры

iex> Enum.zip_with([1, 2], [3, 4], fn x, y -> x + y end)
[4, 6]

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

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

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

Spec-Zone.ru

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