Spec-Zone.ru › Elixir 1.13

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)

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

frequencies(enumerable)

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

frequencies_by(enumerable, key_fun)

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

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

Разбивает перечислимый объект на группы на основе 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)

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

map_reduce(enumerable, acc, fun)

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

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

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

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 согласно порядку Эрланга.

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)

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

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 согласно порядку Эрланга.

sort(enumerable, fun)

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

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

Сортирует отображенные результаты 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?(enumerable)Source

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

@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?(enumerable)Source

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

@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(enumerable, index, default \\ nil)Source

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

@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(enumerable, count)Source

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

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

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

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

chunk_while(enumerable, acc, chunk_fun, after_fun)Source

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

Разбивает enumerable на фрагменты с тонкозернистым управлением при выводе каждого фрагмента.

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

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

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

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

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

@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(left, right)Source

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

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

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

Примеры

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

count(enumerable, fun)Source

@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(enumerable, limit)Source

@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

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

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

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

Сопоставляет и сводит 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}

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"

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 апреля, потому что структурное сравнение сравнивает день перед годом. По этой причине большинство структур предоставляют функцию "compare", такую как 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"

Тот факт, что эта функция использует порядок терминов Erlang, означает, что сравнение является структурным, а не семантическим. Поэтому, если вы хотите сравнить структуры, большинство структур предоставляют функцию "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 в соответствии с порядком терминов Erlang.

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

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

Примеры

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

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

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"

Тот факт, что эта функция использует порядок терминов Erlang, означает, что сравнение является структурным, а не семантическим. Поэтому, если вы хотите сравнить структуры, большинство структур предоставляют функцию "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()

Возвращает кортеж с минимальными и максимальными элементами в перечислителе согласно порядку терминов 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(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}

Тот факт, что эта функция использует порядок терминов Erlang, означает, что сравнение является структурным, а не семантическим. Поэтому, если вы хотите сравнить структуры, большинство структур предоставляют функцию "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()

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

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

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

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

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

Примеры

Примеры ниже используют псевдослучайный алгоритм :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, которые оптимизированы в runtime.

Например, мы могли бы реализовать 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 :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. Учитывая диапазон, он пропускает элементы перед index_range.first (нумерация с нуля), а затем берет элементы до элемента index_range.last (включительно).

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

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

Если нормализованный index_range.first выходит за пределы границ данного enumerable, или он больше нормализованного 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]

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

iex> Enum.slice(1..30, 25..-1//1)
[26, 27, 28, 29, 30]

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

iex> Enum.slice(1..10, 11..20)
[]

# first is greater than last
iex> Enum.slice(1..10, 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]

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

slide(enumerable, range_or_single_index, insertion_index)Source

Сдвигает один или несколько элементов, заданных 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, fun)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"]

Возрастание и убывание

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, что является обратным тому, что мы хотим.

По этой причине большинство структур предоставляют функцию «compare», такую как 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 \\ &<=/2)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, которая по умолчанию равна 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"]

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

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, &>=/2)
["monster", "some", "kind", "of"]

Или используйте :asc и :desc:

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

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

Разделяет перечисляемый объект на две части в позиции элемента, для которого 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 с 1 аргументом. Затем второй элемент из каждого перечисляемого объекта помещается в список и передается 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]
END_OF_DOCUMENT_MARKER

zip_with(enumerable1, enumerable2, zip_fun)Source

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

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

Соответствующие элементы из каждого набора передаются предоставленной функции zip_fun с 2 аргументами по очереди. Возвращает список, содержащий результат вызова 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.13.4/Enum.html

Spec-Zone.ru

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