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.
Краткое описание
Типы
- index()
Индекс, начинающийся с нуля. Также может быть отрицательным целым числом.
Функции
- all?(enumerable, fun \\ fn x -> x end)
Возвращает
trueеслиfun.(element)истинно для всех элементов вenumerable.- any?(enumerable, fun \\ fn x -> x end)
Возвращает
trueеслиfun.(element)истинно хотя бы для одного элемента вenumerable.- at(enumerable, index, default \\ nil)
Находит элемент по заданному
index(нумерация с нуля).- chunk_by(enumerable, fun)
Разбивает перечисляемый объект на группы по каждому элементу, для которого
funвозвращает новое значение.- chunk_every(enumerable, count)
Сокращение для
chunk_every(enumerable, count, count).- chunk_every(enumerable, count, step, leftover \\ [])
Возвращает список списков, содержащих по
countэлементов каждый, где каждая новая группа начинается сstepэлемента вenumerable.- chunk_while(enumerable, acc, chunk_fun, after_fun)
Разбивает перечисляемый объект на группы с точным управлением, когда каждая группа передается.
- concat(enumerables)
Принимая перечисляемый объект перечисляемых объектов, конкатенирует
enumerablesв один список.- concat(left, right)
Конкатенирует перечисляемый объект слева с перечисляемым объектом справа.
- count(enumerable)
Возвращает размер
enumerable.- count(enumerable, fun)
Возвращает количество элементов в
enumerableдля которыхfunвозвращает истинное значение.- dedup(enumerable)
Перечисляет
enumerable, возвращая список, где все последовательные дублирующиеся элементы сводятся к одному элементу.- dedup_by(enumerable, fun)
Перечисляет
enumerable, возвращая список, где все последовательные дублирующиеся элементы сводятся к одному элементу.- drop(enumerable, amount)
Опускает
amountэлементов изenumerable.- drop_every(enumerable, nth)
Возвращает список каждых
nthэлементов вenumerableпосле удаления, начиная с первого элемента.- drop_while(enumerable, fun)
Опускает элементы в начале
enumerableпокаfunвозвращает истинное значение.- each(enumerable, fun)
Вызывает заданную
funдля каждого элемента вenumerable.- empty?(enumerable)
Определяет, является ли
enumerableпустым.- fetch(enumerable, index)
Находит элемент по заданному
index(нумерация с нуля).- fetch!(enumerable, index)
Находит элемент по заданному
index(нумерация с нуля).- filter(enumerable, fun)
Фильтровать
enumerable, т.е. возвращает только те элементы, для которыхfunвозвращает истинное значение.- find(enumerable, default \\ nil, fun)
Возвращает первый элемент, для которого
funвозвращает истинное значение. Если такой элемент не найден, возвращаетdefault.- find_index(enumerable, fun)
Аналогично
find/3, но возвращает индекс (нумерация с нуля) элемента вместо самого элемента.- find_value(enumerable, default \\ nil, fun)
Аналогично
find/3, но возвращает значение вызова функции вместо самого элемента.- flat_map(enumerable, fun)
Применяет заданный
funкenumerableи сплющивает результат.- flat_map_reduce(enumerable, acc, fun)
Применяет и сводит перечисляемый объект, сплющивая полученные результаты (только один уровень вглубь).
- 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, element)
Вставляет
elementмежду каждым элементом перечисления.- into(enumerable, collectable)
Вставляет данный
enumerableвcollectable.- into(enumerable, collectable, transform)
Вставляет данный
enumerableвcollectableв соответствии с функцией преобразования.- join(enumerable, joiner \\ "")
Объединяет данный
enumerableв строку, используяjoinerв качестве разделителя.- map(enumerable, fun)
Возвращает список, где каждый элемент является результатом вызова
funдля каждого соответствующего элементаenumerable.- map_every(enumerable, nth, fun)
Возвращает список результатов вызова
funдля каждогоnthэлементаenumerable, начиная с первого элемента.- map_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)
Возвращает кортеж с минимальным и максимальным элементами в перечисляемом объекте согласно порядку терминов Erlang.
- min_max_by(enumerable, fun, empty_fallback \\ fn -> raise(Enum.EmptyError) end)
Возвращает кортеж с минимальным и максимальным элементами в перечисляемом объекте, рассчитанными с помощью заданной функции.
- random(enumerable)
Возвращает случайный элемент перечисляемого объекта.
- reduce(enumerable, fun)
Вызывает
funдля каждого элемента в перечисляемом объекте с аккумулятором.- reduce(enumerable, acc, fun)
Вызывает
funдля каждого элемента в перечисляемом объекте с аккумулятором.- reduce_while(enumerable, acc, fun)
Редуцирует
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количеством элементов, если они доступны.- sort(enumerable)
Сортирует
enumerableв соответствии с порядком терминов Erlang.- 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(enumerable)
Обратное
zip/2. Извлекает пары из двух элементов из данногоenumerableи группирует их.- with_index(enumerable, offset \\ 0)
Возвращает
enumerableс каждым элементом, заключённым в кортеж вместе с его индексом.- zip(enumerables)
Объединяет соответствующие элементы из конечного набора перечисляемых объектов в один список кортежей.
- zip(enumerable1, enumerable2)
Объединяет соответствующие элементы из двух перечисляемых объектов в один список кортежей.
Типы
acc()
Спецификации
acc() :: any()
default()
Спецификации
default() :: any()
element()
Спецификации
element() :: any()
index()
Спецификации
index() :: integer()
Индекс с нулевой базой. Также может быть отрицательным целым числом.
t()
Спецификации
t() :: Enumerable.t()
Функции
all?(перечисляемый, функция \\ fn x -> x end)
Характеристики
all?(t(), (element() -> as_boolean(term()))) :: boolean()
Возвращает true если fun.(element) истинно для всех элементов в enumerable.
Перебирает enumerable и вызывает fun для каждого элемента. Когда вызов fun возвращает ложное значение (false или nil) итерация останавливается немедленно, и возвращается false. Во всех других случаях возвращается true.
Примеры
iex> Enum.all?([2, 4, 6], fn x -> rem(x, 2) == 0 end) true iex> Enum.all?([2, 3, 4], fn x -> rem(x, 2) == 0 end) false iex> Enum.all?([], fn x -> x > 0 end) true
Если функция не задана, истинность каждого элемента проверяется во время итерации. Когда элемент имеет ложное значение (false или nil) итерация останавливается немедленно, и возвращается false. Во всех других случаях возвращается true.
iex> Enum.all?([1, 2, 3]) true iex> Enum.all?([1, nil, 3]) false iex> Enum.all?([]) true
any?(перечисляемый, функция \\ fn x -> x end)
Характеристики
any?(t(), (element() -> as_boolean(term()))) :: boolean()
Возвращает true если fun.(element) истинно хотя бы для одного элемента в enumerable.
Перебирает enumerable и вызывает fun для каждого элемента. Когда вызов fun возвращает истинное значение (ни false ни nil) итерация останавливается немедленно, и возвращается true. Во всех других случаях возвращается false.
Примеры
iex> Enum.any?([2, 4, 6], fn x -> rem(x, 2) == 1 end) false iex> Enum.any?([2, 3, 4], fn x -> rem(x, 2) == 1 end) true iex> Enum.any?([], fn x -> x > 0 end) false
Если функция не задана, истинность каждого элемента проверяется во время итерации. Когда элемент имеет истинное значение (ни false ни nil) итерация останавливается немедленно, и возвращается true. Во всех других случаях возвращается false.
iex> Enum.any?([false, false, false]) false iex> Enum.any?([false, true, false]) true iex> Enum.any?([]) false
at(перечисляемый, индекс, значение_по_умолчанию \\ nil)
Характеристики
at(t(), index(), default()) :: element() | default()
Находит элемент по заданному index (нумерация с нуля).
Возвращает default если index выходит за пределы границ.
Можно использовать отрицательный index, что означает, что enumerable перебирается один раз, а index подсчитывается с конца (например, -1 находит последний элемент).
Примеры
iex> Enum.at([2, 4, 6], 0) 2 iex> Enum.at([2, 4, 6], 2) 6 iex> Enum.at([2, 4, 6], 4) nil iex> Enum.at([2, 4, 6], 4, :none) :none
chunk_by(перечисляемый, функция)
Характеристики
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(перечисляемый, количество)
Характеристики
chunk_every(t(), pos_integer()) :: [list()]
Краткая запись для chunk_every(enumerable, count, count).
chunk_every(перечисляемый, количество, шаг, остаток \\ [])
Характеристики
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(перечисляемый, накопитель, функция_группировки, функция_после)
Характеристики
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} для того, чтобы не выдавать группу и продолжить с возвращаемым накопителем.
after_fun вызывается при завершении итерации и также должна вернуть {:cont, chunk, acc} или {:cont, acc}.
Возвращает список списков.
Примеры
iex> chunk_fun = fn element, acc ->
...> if rem(element, 2) == 0 do
...> {:cont, Enum.reverse([element | acc]), []}
...> else
...> {:cont, [element | acc]}
...> end
...> end
iex> after_fun = fn
...> [] -> {:cont, []}
...> acc -> {:cont, Enum.reverse(acc), []}
...> end
iex> Enum.chunk_while(1..10, [], chunk_fun, after_fun)
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] concat(перечисляемые)
Характеристики
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(слева, справа)
Характеристики
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(перечисляемый)
Характеристики
count(t()) :: non_neg_integer()
Возвращает размер enumerable.
Примеры
iex> Enum.count([1, 2, 3]) 3
count(перечисляемый, функция)
Характеристики
count(t(), (element() -> as_boolean(term()))) :: non_neg_integer()
Возвращает количество элементов в enumerable для которых fun возвращает истинное значение.
Примеры
iex> Enum.count([1, 2, 3, 4, 5], fn x -> rem(x, 2) == 0 end) 2
dedup(перечисляемый)
Характеристики
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(перечисляемый, функция)
Характеристики
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(перечисляемый, количество)
Характеристики
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(перечисляемый, n-й)
Характеристики
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(перечисляемый, функция)
Характеристики
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(перечисляемый, функция)
Характеристики
each(t(), (element() -> any())) :: :ok
Вызывает заданную fun для каждого элемента в enumerable.
Возвращает :ok.
Примеры
Enum.each(["some", "example"], fn x -> IO.puts(x) end) "some" "example" #=> :ok
empty?(перечисляемый)
Характеристики
empty?(t()) :: boolean()
Определяет, является ли enumerable пустым.
Возвращает true если enumerable пустой, в противном случае false.
Примеры
iex> Enum.empty?([]) true iex> Enum.empty?([1, 2, 3]) false
fetch(enumerable, index)
Спецификации
fetch(t(), index()) :: {:ok, element()} | :error Находит элемент по заданному index (нумерация с нуля).
Возвращает {:ok, element} при нахождении, в противном случае :error.
Можно передать отрицательный index, что означает, что enumerable перечисляется один раз, а index подсчитывается с конца (например, -1 извлекает последний элемент).
Примеры
iex> Enum.fetch([2, 4, 6], 0)
{:ok, 2}
iex> Enum.fetch([2, 4, 6], -3)
{:ok, 2}
iex> Enum.fetch([2, 4, 6], 2)
{:ok, 6}
iex> Enum.fetch([2, 4, 6], 4)
:error fetch!(enumerable, index)
Спецификации
fetch!(t(), index()) :: element()
Находит элемент по заданному index (нумерация с нуля).
Вызывает OutOfBoundsError если заданный index выходит за пределы диапазона enumerable.
Примеры
iex> Enum.fetch!([2, 4, 6], 0) 2 iex> Enum.fetch!([2, 4, 6], 2) 6 iex> Enum.fetch!([2, 4, 6], 4) ** (Enum.OutOfBoundsError) out of bounds error
filter(enumerable, fun)
Спецификации
filter(t(), (element() -> as_boolean(term()))) :: list()
Фильтрует enumerable, т.е. возвращает только те элементы, для которых fun возвращает истинное значение.
См. также reject/2, который отбрасывает все элементы, где функция возвращает истинное значение.
Примеры
iex> Enum.filter([1, 2, 3], fn x -> rem(x, 2) == 0 end) [2]
Обратите внимание, что filter не может одновременно фильтровать и преобразовывать элемент. Если вам нужно это сделать, рассмотрите использование flat_map/2. Например, если вам нужно преобразовать все строки, представляющие целое число, и отбросить недействительные в одном проходе:
strings = ["1234", "abc", "12ab"]
Enum.flat_map(strings, fn string ->
case Integer.parse(string) do
# transform to integer
{int, _rest} -> [int]
# skip the value
:error -> []
end
end) find(enumerable, default \\ nil, fun)
Спецификации
find(t(), default(), (element() -> any())) :: element() | default()
Возвращает первый элемент, для которого fun возвращает истинное значение. Если такой элемент не найден, возвращает default.
Примеры
iex> Enum.find([2, 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)
Спецификации
find_index(t(), (element() -> any())) :: non_neg_integer() | nil
Аналогично find/3, но возвращает индекс (нумерация с нуля) элемента вместо самого элемента.
Примеры
iex> Enum.find_index([2, 4, 6], fn x -> rem(x, 2) == 1 end) nil iex> Enum.find_index([2, 3, 4], fn x -> rem(x, 2) == 1 end) 1
find_value(enumerable, default \\ nil, fun)
Спецификации
find_value(t(), any(), (element() -> any())) :: any() | nil
Аналогично find/3, но возвращает значение вызова функции вместо самого элемента.
Возвращаемое значение считается найденным, когда результат истинен (ни 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)
Спецификации
flat_map(t(), (element() -> t())) :: list()
Применяет данную fun к enumerable и уплощает результат.
Эта функция возвращает новый перечислимый набор, составленный путём добавления результата вызова fun для каждого элемента enumerable вместе; концептуально это аналогично сочетанию map/2 и concat/1.
Примеры
iex> Enum.flat_map([:a, :b, :c], fn x -> [x, x] end)
[:a, :a, :b, :b, :c, :c]
iex> Enum.flat_map([{1, 3}, {4, 6}], fn {x, y} -> x..y end)
[1, 2, 3, 4, 5, 6]
iex> Enum.flat_map([:a, :b, :c], fn x -> [[x]] end)
[[:a], [:b], [:c]] flat_map_reduce(enumerable, acc, fun)
Спецификации
flat_map_reduce(t(), acc(), fun) :: {[any()], acc()}
when fun: (element(), acc() -> {t(), acc()} | {:halt, acc()}) Преобразует и сводит перечислимый набор, уплощая полученные результаты (только один уровень глубины).
Ожидает аккумулятора и функции, которая получает каждый элемент перечислимого набора и должна возвращать кортеж, содержащий новый перечислимый набор (часто список) с новым аккумулятором или кортеж с :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)
Спецификации
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)
Спецификации
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)
Спецификации
group_by(t(), (element() -> any()), (element() -> any())) :: map()
Разделяет перечислимый набор на группы на основе enumerable.
Результат — это карта, где каждый ключ задаётся key_fun, а каждое значение — это список элементов, заданных value_fun . Порядок элементов в каждом списке сохраняется из enumerable . Однако, как и все карты, полученная карта не упорядочена.
Примеры
iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1)
%{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1)
%{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]} intersperse(enumerable, element)
Спецификации
intersperse(t(), element()) :: list()
Вставляет element между каждым элементом перечисления.
Примеры
iex> Enum.intersperse([1, 2, 3], 0) [1, 0, 2, 0, 3] iex> Enum.intersperse([1], 0) [1] iex> Enum.intersperse([], 0) []
into(enumerable, collectable)
Спецификации
into(Enumerable.t(), Collectable.t()) :: Collectable.t()
Вставляет данный enumerable в collectable.
Обратите внимание, что передача непустого списка в качестве collectable устарела. Если вы собираете в непустой список ключевых слов, рассмотрите использование Keyword.merge/2. Если вы собираете в непустой список, рассмотрите что-то вроде to_list(enumerable) ++ collectable.
Примеры
iex> Enum.into([1, 2], [])
[1, 2]
iex> Enum.into([a: 1, b: 2], %{})
%{a: 1, b: 2}
iex> Enum.into(%{a: 1}, %{b: 2})
%{a: 1, b: 2}
iex> Enum.into([a: 1, a: 2], %{})
%{a: 2} into(enumerable, collectable, transform)
Спецификации
into(Enumerable.t(), Collectable.t(), (term() -> term())) :: Collectable.t()
Вставляет данный enumerable в collectable в соответствии с функцией преобразования.
Примеры
iex> Enum.into([2, 3], [3], fn x -> x * 3 end)
[3, 6, 9]
iex> Enum.into(%{a: 1, b: 2}, %{c: 3}, fn {k, v} -> {k, v * 2} end)
%{a: 2, b: 4, c: 3} join(enumerable, joiner \\ "")
Спецификации
join(t(), String.t()) :: String.t()
Объединяет данный enumerable в двоичный объект, используя joiner в качестве разделителя.
Если joiner не передаётся вообще, он по умолчанию равен пустому двоичному объекту.
Все элементы в enumerable должны быть преобразуемы в двоичный объект, в противном случае возникает ошибка.
Примеры
iex> Enum.join([1, 2, 3]) "123" iex> Enum.join([1, 2, 3], " = ") "1 = 2 = 3"
map(enumerable, fun)
Спецификации
map(t(), (element() -> any())) :: list()
Возвращает список, где каждый элемент — результат вызова fun для каждого соответствующего элемента enumerable.
Для карт функция ожидает кортеж ключ-значение.
Примеры
iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
[2, 4, 6]
iex> Enum.map([a: 1, b: 2], fn {k, v} -> {k, -v} end)
[a: -1, b: -2] map_every(enumerable, nth, fun)
Спецификации
map_every(t(), non_neg_integer(), (element() -> any())) :: list()
Возвращает список результатов вызова fun для каждого nth элемента enumerable, начиная с первого элемента.
Первый элемент всегда передаётся в заданную функцию, если nth не равен 0.
Второй аргумент, определяющий каждый nth элемент, должен быть целым числом без знака.
Если nth равен 0, то enumerable напрямую преобразуется в список без применения fun.
Примеры
iex> Enum.map_every(1..10, 2, fn x -> x + 1000 end) [1001, 2, 1003, 4, 1005, 6, 1007, 8, 1009, 10] iex> Enum.map_every(1..10, 3, fn x -> x + 1000 end) [1001, 2, 3, 1004, 5, 6, 1007, 8, 9, 1010] iex> Enum.map_every(1..5, 0, fn x -> x + 1000 end) [1, 2, 3, 4, 5] iex> Enum.map_every([1, 2, 3], 1, fn x -> x + 1000 end) [1001, 1002, 1003]
map_intersperse(enumerable, separator, mapper)
Спецификации
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)
Спецификации
map_join(t(), String.t(), (element() -> String.Chars.t())) :: String.t()
Преобразует и объединяет данный enumerable в одном проходе.
joiner может быть либо двоичным объектом, либо списком, и результат будет того же типа, что и joiner . Если joiner не передаётся вообще, он по умолчанию равен пустому двоичному объекту.
Все элементы, возвращённые от вызова mapper , должны быть преобразуемы в двоичные объекты, в противном случае возникает ошибка.
Примеры
iex> Enum.map_join([1, 2, 3], &(&1 * 2)) "246" iex> Enum.map_join([1, 2, 3], " = ", &(&1 * 2)) "2 = 4 = 6"
map_reduce(enumerable, acc, fun)
Характеристики
map_reduce(t(), acc(), (element(), acc() -> {element(), acc()})) ::
{list(), acc()} Вызывает заданную функцию для каждого элемента в enumerable, чтобы свести его к одному элементу, сохраняя при этом аккумулятор.
Возвращает кортеж, где первый элемент — это преобразованное множество, а второй — конечный аккумулятор.
Функция fun, получает два аргумента: первый — это элемент, а второй — аккумулятор. fun должна возвращать кортеж с двумя элементами в формате {result, accumulator}.
Для преобразований первый элемент кортежа должен быть кортежем {key, value}.
Примеры
iex> Enum.map_reduce([1, 2, 3], 0, fn x, acc -> {x * 2, x + acc} end)
{[2, 4, 6], 6} max(enumerable, sorter \\ &>=/2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)
Характеристики
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)
Характеристики
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)
Характеристики
member?(t(), element()) :: boolean()
Проверяет, существует ли element в enumerable.
Членство проверяется с помощью оператора совпадения (===/2).
Примеры
iex> Enum.member?(1..10, 5) true iex> Enum.member?(1..10, 5.0) false iex> Enum.member?([1.0, 2.0, 3.0], 2) false iex> Enum.member?([1.0, 2.0, 3.0], 2.000) true iex> Enum.member?([:a, :b, :c], :d) false
min(enumerable, sorter \\ &<=/2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)
Характеристики
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)
Характеристики
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)
Характеристики
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, empty_fallback \\ fn -> raise(Enum.EmptyError) end)
Характеристики
min_max_by(t(), (element() -> any()), (() -> empty_result)) ::
{element(), element()} | empty_result
when empty_result: any() Возвращает кортеж с минимальным и максимальным элементами в перечислимом наборе, рассчитанными с помощью предоставленной функции.
Если несколько элементов считаются максимальными или минимальными, возвращается первый найденный.
Вызывает предоставленную empty_fallback функцию и возвращает её значение, если enumerable пусто. По умолчанию empty_fallback генерирует Enum.EmptyError.
Примеры
iex> Enum.min_max_by(["aaa", "bb", "c"], fn x -> String.length(x) end)
{"c", "aaa"}
iex> Enum.min_max_by(["aaa", "a", "bb", "c", "ccc"], &String.length/1)
{"a", "aaa"}
iex> Enum.min_max_by([], &String.length/1, fn -> {nil, nil} end)
{nil, nil} random(enumerable)
Характеристики
random(t()) :: element()
Возвращает случайный элемент из перечислимого enumerable.
Вызывает исключение Enum.EmptyError, если enumerable пусто.
Эта функция использует модуль Erlang's :rand модуль для расчета случайного значения. Проверьте его документацию для изменения алгоритма генерации случайных чисел или начального значения.
Реализация основана на алгоритме выборки резервуара. Предполагается, что возвращаемый образец помещается в память; входной enumerable не обязательно должен быть помещен в память, так как он проходит только один раз.
Если в функцию передаётся диапазон, эта функция выберет случайное значение между границами диапазона, не просматривая весь диапазон (следовательно, выполняется за постоянное время и постоянную память).
Примеры
В примерах ниже используется псевдослучайный алгоритм :exrop, так как он является стандартным для Erlang/OTP 20. Однако, если вы используете Erlang/OTP 22 или более позднюю версию, то по умолчанию используется алгоритм :exsss. Если вы используете :exsplus, то пожалуйста, обновитесь, так как этот алгоритм устарел с Erlang/OTP 20.
# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exrop, {101, 102, 103})
iex> Enum.random([1, 2, 3])
3
iex> Enum.random([1, 2, 3])
2
iex> Enum.random(1..1_000)
846 reduce(enumerable, fun)
Характеристики
reduce(t(), (element(), acc() -> acc())) :: acc()
Вызывает fun для каждого элемента в enumerable с накопителем.
Вызывает исключение Enum.EmptyError, если enumerable пусто.
Первый элемент enumerable используется в качестве начального значения накопителя. Затем функция вызывается с последующим элементом и накопителем. Результат, возвращаемый функцией, используется в качестве накопителя для следующей итерации рекурсивно. Когда обработка enumerable завершена, возвращается последний накопитель.
Поскольку первый элемент перечислимого используется в качестве начального значения накопителя, fun будет выполняться только n - 1 раз, где n - длина перечислимого. Эта функция не будет вызывать указанную функцию для перечислимых элементов длиной в один элемент.
Если вы хотите использовать другое значение для накопителя, используйте Enum.reduce/3.
Примеры
iex> Enum.reduce([1, 2, 3, 4], fn x, acc -> x * acc end) 24
reduce(enumerable, acc, fun)
Характеристики
reduce(t(), any(), (element(), any() -> any())) :: any()
Вызывает fun для каждого элемента в enumerable с накопителем.
Начальное значение накопителя — acc. Функция вызывается для каждого элемента в перечислимом с накопителем. Результат, возвращаемый функцией, используется в качестве накопителя для следующей итерации. Функция возвращает последний накопитель.
Примеры
iex> Enum.reduce([1, 2, 3], 0, fn x, acc -> x + acc end) 6
Reduce как строительный блок
Reduce (иногда называемый fold) — базовый строительный блок в функциональном программировании. Практически все функции в модуле Enum могут быть реализованы на основе reduce. Эти функции часто опираются на другие операции, такие как Enum.reverse/1, которые оптимизированы в среде выполнения.
Например, мы можем реализовать map/2 в терминах reduce/3 следующим образом:
def my_map(enumerable, fun) do enumerable |> Enum.reduce([], fn x, acc -> [fun.(x) | acc] end) |> Enum.reverse() end
В примере выше, Enum.reduce/3 накапливает результат каждого вызова fun в список в обратном порядке, который правильно упорядочивается в конце путём вызова Enum.reverse/1.
Реализация функций, таких как map/2, filter/2 и других, является хорошим упражнением для понимания мощи Enum.reduce/3. Когда операция не может быть выражена ни одной из функций в модуле Enum, разработчики, скорее всего, прибегнут к reduce/3.
reduce_while(enumerable, acc, fun)
Характеристики
reduce_while(t(), any(), (element(), any() -> {:cont, any()} | {:halt, any()})) ::
any() Уменьшает enumerable до тех пор, пока fun не вернёт {:halt, term}.
Ожидаемое возвращаемое значение fun:
-
{:cont, acc}для продолжения сокращения сaccв качестве нового накопителя или -
{:halt, acc}для остановки сокращения
Если fun вернёт {:halt, acc} , сокращение останавливается, и функция возвращает acc. В противном случае, если перечислимый объект исчерпан, функция возвращает накопитель последнего {:cont, acc}.
Примеры
iex> Enum.reduce_while(1..100, 0, fn x, acc ->
...> if x < 5, do: {:cont, acc + x}, else: {:halt, acc}
...> end)
10
iex> Enum.reduce_while(1..100, 0, fn x, acc ->
...> if x > 0, do: {:cont, acc + x}, else: {:halt, acc}
...> end)
5050 reject(enumerable, fun)
Характеристики
reject(t(), (element() -> as_boolean(term()))) :: list()
Возвращает список элементов в enumerable за исключением тех, для которых функция fun возвращает истинное значение.
См. также filter/2.
Примеры
iex> Enum.reject([1, 2, 3], fn x -> rem(x, 2) == 0 end) [1, 3]
reverse(enumerable)
Характеристики
reverse(t()) :: list()
Возвращает список элементов в enumerable в обратном порядке.
Примеры
iex> Enum.reverse([1, 2, 3]) [3, 2, 1]
reverse(enumerable, tail)
Характеристики
reverse(t(), t()) :: list()
Инвертирует элементы в enumerable, добавляет tail, и возвращает их как список.
Это оптимизация для enumerable |> Enum.reverse() |> Enum.concat(tail).
Примеры
iex> Enum.reverse([1, 2, 3], [4, 5, 6]) [3, 2, 1, 4, 5, 6]
reverse_slice(enumerable, start_index, count)
Характеристики
reverse_slice(t(), non_neg_integer(), non_neg_integer()) :: list()
Инвертирует enumerable в диапазоне от начального start_index до count элементов.
Если count больше, чем размер остальной части enumerable , эта функция инвертирует остальную часть перечислимого объекта.
Примеры
iex> Enum.reverse_slice([1, 2, 3, 4, 5, 6], 2, 4) [1, 2, 6, 5, 4, 3]
scan(enumerable, fun)
Характеристики
scan(t(), (element(), any() -> any())) :: list()
Применяет данную функцию к каждому элементу в перечислимом enumerable, сохраняя результат в списке и передавая его в качестве накопителя для следующего вычисления. Использует первый элемент в enumerable в качестве начального значения.
Примеры
iex> Enum.scan(1..5, &(&1 + &2)) [1, 3, 6, 10, 15]
scan(enumerable, acc, fun)
Характеристики
scan(t(), any(), (element(), any() -> any())) :: list()
Применяет данную функцию к каждому элементу в перечислимом enumerable, сохраняя результат в списке и передавая его в качестве накопителя для следующего вычисления. Использует заданное acc в качестве начального значения.
Примеры
iex> Enum.scan(1..5, 0, &(&1 + &2)) [1, 3, 6, 10, 15]
shuffle(enumerable)
Характеристики
shuffle(t()) :: list()
Возвращает список со случайным порядком элементов enumerable.
Эта функция использует модуль Erlang's :rand модуль для расчета случайного значения. Проверьте его документацию для изменения алгоритма генерации случайных чисел или начального значения.
Примеры
В примерах ниже используется псевдослучайный алгоритм :exrop, так как он является стандартным для Erlang/OTP 20. Однако, если вы используете Erlang/OTP 22 или более позднюю версию, то по умолчанию используется алгоритм :exsss. Если вы используете :exsplus, то пожалуйста, обновитесь, так как этот алгоритм устарел с Erlang/OTP 20.
# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exrop, {1, 2, 3})
iex> Enum.shuffle([1, 2, 3])
[3, 1, 2]
iex> Enum.shuffle([1, 2, 3])
[1, 3, 2] slice(enumerable, index_range)
Характеристики
slice(t(), Range.t()) :: list()
Возвращает подмножество списка заданного перечислимого enumerable с помощью index_range.
index_range должен быть Range. При заданном enumerable, он отбрасывает элементы до index_range.first (нумерация с нуля), затем берет элементы до элемента index_range.last (включительно).
Индексы нормализуются, что означает, что отрицательные индексы будут считаться с конца (например, -1 означает последний элемент enumerable).
Если index_range.last выходит за пределы, он присваивается в качестве индекса последнего элемента.
Если нормализованный index_range.first выходит за пределы заданного enumerable или он больше нормализованного index_range.last, то возвращается [].
Примеры
iex> Enum.slice(1..100, 5..10) [6, 7, 8, 9, 10, 11] iex> Enum.slice(1..10, 5..20) [6, 7, 8, 9, 10] # last five elements (negative indexes) iex> Enum.slice(1..30, -5..-1) [26, 27, 28, 29, 30] # last five elements (mixed positive and negative indexes) iex> Enum.slice(1..30, 25..-1) [26, 27, 28, 29, 30] # out of bounds iex> Enum.slice(1..10, 11..20) [] # first is greater than last iex> Enum.slice(1..10, 6..5) []
slice(enumerable, start_index, amount)
Характеристики
slice(t(), index(), non_neg_integer()) :: list()
Возвращает подмножество списка заданного перечисляемого, начиная с индекса start_index (нумерация с нуля) с количеством элементов amount, если они доступны.
Для заданного перечисляемого, он пропускает элементы перед элементом start_index, затем берет amount элементов, возвращая как можно больше элементов, если их недостаточно.
Можно передать отрицательный start_index, что означает, что перечисление enumerable происходит один раз, и индекс вычисляется с конца (например, -1 начинает срезы с последнего элемента).
Возвращает [], если amount равно 0 или если start_index выходит за пределы границ.
Примеры
iex> Enum.slice(1..100, 5, 10) [6, 7, 8, 9, 10, 11, 12, 13, 14, 15] # amount to take is greater than the number of elements iex> Enum.slice(1..10, 5, 100) [6, 7, 8, 9, 10] iex> Enum.slice(1..10, 5, 0) [] # using a negative start index iex> Enum.slice(1..10, -6, 3) [5, 6, 7] # out of bound start index (positive) iex> Enum.slice(1..10, 10, 5) [] # out of bound start index (negative) iex> Enum.slice(1..10, -11, 5) []
sort(enumerable)
Характеристики
sort(t()) :: list()
Сортирует перечисляемое в соответствии с порядком Erlang.
Эта функция использует алгоритм слияния. Не используйте эту функцию для сортировки структур, см. sort/2 для получения дополнительной информации.
Примеры
iex> Enum.sort([3, 2, 1]) [1, 2, 3]
sort(enumerable, fun)
Характеристики
sort(
t(),
(element(), element() -> boolean())
| :asc
| :desc
| module()
| {:asc | :desc, module()}
) :: list() Сортирует перечисляемое с помощью заданной функции.
Эта функция использует алгоритм слияния. Переданная функция должна сравнивать два аргумента и возвращать 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)
Характеристики
sort_by(
t(),
(element() -> mapped_element),
(element(), element() -> boolean())
| :asc
| :desc
| module()
| {:asc | :desc, module()}
) :: list()
when mapped_element: element() Сортирует полученные в результате преобразования элементы перечисляемого в соответствии с предоставленной функцией.
Эта функция преобразует каждый элемент перечисляемого с помощью предоставленной функции. Перечисляемое затем сортируется по преобразованным элементам с помощью функции sorter, которая по умолчанию равна Kernel.<=/2.
sort_by/3 отличается от sort/2 тем, что вычисляет значение сравнения для каждого элемента перечисляемого только один раз вместо одного раза для каждого элемента в каждом сравнении. Если для обоих элементов вызывается одна и та же функция, эффективнее использовать sort_by/3.
Примеры
Используя стандартную функцию <=/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)
Характеристики
split(t(), integer()) :: {list(), list()} Разделяет перечисляемое на два перечисляемых, оставляя count элементов в первом.
Если count отрицательное число, отсчет ведётся с конца перечисляемого.
Обратите внимание, что отрицательное count подразумевает, что перечисляемое будет перечислено дважды: один раз для расчета позиции и второй раз для фактического разделения.
Примеры
iex> Enum.split([1, 2, 3], 2)
{[1, 2], [3]}
iex> Enum.split([1, 2, 3], 10)
{[1, 2, 3], []}
iex> Enum.split([1, 2, 3], 0)
{[], [1, 2, 3]}
iex> Enum.split([1, 2, 3], -1)
{[1, 2], [3]}
iex> Enum.split([1, 2, 3], -5)
{[], [1, 2, 3]} split_while(enumerable, fun)
Характеристики
split_while(t(), (element() -> as_boolean(term()))) :: {list(), list()} Разделяет перечисляемое на две части в позиции элемента, для которого fun возвращает ложное значение (false или nil).
Возвращает кортеж из двух списков элементов. Элемент, вызвавший разделение, входит во второй список.
Примеры
iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 3 end)
{[1, 2], [3, 4]}
iex> Enum.split_while([1, 2, 3, 4], fn x -> x < 0 end)
{[], [1, 2, 3, 4]}
iex> Enum.split_while([1, 2, 3, 4], fn x -> x > 0 end)
{[1, 2, 3, 4], []} split_with(enumerable, fun)
Характеристики
split_with(t(), (element() -> as_boolean(term()))) :: {list(), list()} Разделяет перечисляемое на два списка в соответствии с заданной функцией fun.
Разделяет заданное перечисляемое на два списка, вызывая fun с каждым элементом перечисляемого в качестве единственного аргумента. Возвращает кортеж с первым списком, содержащим все элементы из enumerable , для которых применение fun вернуло истинное значение, и второй список со всеми элементами, для которых применение fun вернуло ложное значение (false или nil).
Элементы в обоих возвращённых списках находятся в том же относительном порядке, что и в исходном перечисляемом (если такое перечисляемое было упорядоченным, как список). См. примеры ниже.
Примеры
iex> Enum.split_with([5, 4, 3, 2, 1, 0], fn x -> rem(x, 2) == 0 end)
{[4, 2, 0], [5, 3, 1]}
iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v < 0 end)
{[b: -2, d: -3], [a: 1, c: 1]}
iex> Enum.split_with(%{a: 1, b: -2, c: 1, d: -3}, fn {_k, v} -> v > 50 end)
{[], [a: 1, b: -2, c: 1, d: -3]}
iex> Enum.split_with(%{}, fn {_k, v} -> v > 50 end)
{[], []} sum(enumerable)
Характеристики
sum(t()) :: number()
Возвращает сумму всех элементов.
Вызывает исключение ArithmeticError, если перечисляемое содержит нечисловое значение.
Примеры
iex> Enum.sum([1, 2, 3]) 6
take(enumerable, amount)
Характеристики
take(t(), integer()) :: list()
Возвращает amount элементов из начала или конца перечисляемого.
Если задано положительное количество элементов, возвращаются amount элементов с начала перечисляемого.
Если задано отрицательное количество элементов, возвращаются amount элементов с конца. Перечисляемое перебирается один раз для определения соответствующего индекса, а оставшиеся вычисления выполняются с конца.
Если количество равно 0, возвращается [].
Примеры
iex> Enum.take([1, 2, 3], 2) [1, 2] iex> Enum.take([1, 2, 3], 10) [1, 2, 3] iex> Enum.take([1, 2, 3], 0) [] iex> Enum.take([1, 2, 3], -1) [3]
take_every(enumerable, nth)
Характеристики
take_every(t(), non_neg_integer()) :: list()
Возвращает список каждого nth элемента из перечисляемого, начиная с первого элемента.
Первый элемент всегда включается, если только nth не равно 0.
Второй аргумент, определяющий каждый nth элемент, должен быть неотрицательным целым числом.
Примеры
iex> Enum.take_every(1..10, 2) [1, 3, 5, 7, 9] iex> Enum.take_every(1..10, 0) [] iex> Enum.take_every([1, 2, 3], 1) [1, 2, 3]
take_random(enumerable, count)
Характеристики
take_random(t(), non_neg_integer()) :: list()
Извлекает случайные элементы из перечислимого объекта.
Обратите внимание, что для получения случайного подсписка эта функция пройдет по всему перечислимому объекту.
См. random/1 для заметок об реализации и генерации случайных чисел.
Примеры
# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exrop, {1, 2, 3})
iex> Enum.take_random(1..10, 2)
[7, 2]
iex> Enum.take_random(?a..?z, 5)
'hypnt' take_while(enumerable, fun)
Характеристики
take_while(t(), (element() -> as_boolean(term()))) :: list()
Извлекает элементы из начала перечислимого объекта, пока функция возвращает истинное значение.
Примеры
iex> Enum.take_while([1, 2, 3], fn x -> x < 3 end) [1, 2]
to_list(enumerable)
Характеристики
to_list(t()) :: [element()]
Преобразует перечислимый объект в список.
Примеры
iex> Enum.to_list(1..3) [1, 2, 3]
uniq(enumerable)
Характеристики
uniq(t()) :: list()
Перечисляет элементы, удаляя все дубликаты.
Примеры
iex> Enum.uniq([1, 2, 3, 3, 2, 1]) [1, 2, 3]
uniq_by(enumerable, fun)
Характеристики
uniq_by(t(), (element() -> term())) :: list()
Перечисляет элементы, удаляя элементы, для которых функция возвращает дублированные значения.
Функция сопоставляет каждый элемент со значением. Два элемента считаются дубликатами, если возвращаемое значение функции одинаково для обоих.
Сохраняется первое вхождение каждого элемента.
Пример
iex> Enum.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end)
[{1, :x}, {2, :y}]
iex> Enum.uniq_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn {_, y} -> y end)
[a: {:tea, 2}, c: {:coffee, 1}] unzip(enumerable)
Характеристики
unzip(t()) :: {[element()], [element()]} Обратное zip/2. Извлекает кортежи из двух элементов из данного перечислимого объекта и группирует их.
Принимает перечислимый объект с элементами, являющимися кортежами из двух элементов, и возвращает кортеж из двух списков, каждый из которых образован из первого и второго элементов каждого кортежа соответственно.
Эта функция терпит неудачу, если перечислимый объект не является или не может быть преобразован в список кортежей с ровно двумя элементами в каждом кортеже.
Примеры
iex> Enum.unzip([{:a, 1}, {:b, 2}, {:c, 3}])
{[:a, :b, :c], [1, 2, 3]}
iex> Enum.unzip(%{a: 1, b: 2})
{[:a, :b], [1, 2]} with_index(enumerable, offset \\ 0)
Характеристики
with_index(t(), integer()) :: [{element(), index()}] Возвращает перечислимый объект, где каждый элемент заключен в кортеж вместе с его индексом.
Если задан смещение, индексация начнется с этого смещения вместо нуля.
Примеры
iex> Enum.with_index([:a, :b, :c]) [a: 0, b: 1, c: 2] iex> Enum.with_index([:a, :b, :c], 3) [a: 3, b: 4, c: 5]
zip(enumerables)
Характеристики
zip(enumerables) :: [tuple()] when enumerables: [t()] | t()
Объединяет соответствующие элементы из конечного набора перечислимых объектов в один список кортежей.
Объединение завершается, как только любой перечислимый объект в заданном наборе завершается.
Примеры
iex> Enum.zip([[1, 2, 3], [:a, :b, :c], ["foo", "bar", "baz"]])
[{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}]
iex> Enum.zip([[1, 2, 3, 4, 5], [:a, :b, :c]])
[{1, :a}, {2, :b}, {3, :c}] zip(enumerable1, enumerable2)
Характеристики
zip(t(), t()) :: [{any(), any()}] Объединяет соответствующие элементы из двух перечислимых объектов в один список кортежей.
Объединение завершается, как только любой перечислимый объект завершается.
Примеры
iex> Enum.zip([1, 2, 3], [:a, :b, :c])
[{1, :a}, {2, :b}, {3, :c}]
iex> Enum.zip([1, 2, 3, 4, 5], [:a, :b, :c])
[{1, :a}, {2, :b}, {3, :c}]
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.10.4/Enum.html