Fork me on GitHub

Enum

Набор алгоритмов для операций с коллекциями.

Содержание

Enum

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

Этот урок содержит только небольшую часть функций. Для того, чтобы увидеть полный список функций - посетите официальную документацию по Enum . Для документации по “ленивым” операциям есть отдельная документация в модуле Stream.

all?

При использовании all?, как и большей части Enum в целом, мы передаем функцию, которая будет применяться к элементам коллекции. В случае с all? если хоть один элемент коллекции не вернет true в качестве результата, то результатом будет false:

iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 3 end)
false
iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) > 1 end)
true

any?

И наоборот, any? вернет true если хотя бы один элемент в коллекции выполнится в true:

iex> Enum.any?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 5 end)
true

chunk

Если нужно разбить коллекцию на меньшие группы, метод chunk - это то, что нужно:

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

Также есть несколько дополнительных опций, которые вы можете посмотреть в документации: chunk/2.

chunk_by

Если нужно разделить коллекцию по какому-то другому признаку кроме количества, есть метод chunk_by/2. Он принимает коллекцию и функцию. Когда возвращаемое функцией значение изменяется, начинается формирование новой группы:

iex> Enum.chunk_by(["one", "two", "three", "four", "five"], fn(x) -> String.length(x) end)
[["one", "two"], ["three"], ["four", "five"]]
iex> Enum.chunk_by(["one", "two", "three", "four", "five", "six"], fn(x) -> String.length(x) end)
[["one", "two"], ["three"], ["four", "five"], ["six"]]

each

Когда нужно пройти по коллекции без создания нового значения - используется метод each:

iex> Enum.each(["one", "two", "three"], fn(s) -> IO.puts(s) end)
one
two
three

Замечание: Метод each не возвращает атом :ok.

map

Когда нужно применить функцию для преобразования каждого элемента коллекции - подходит функция map:

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

min

Функция min возвращает минимальное значение коллекции:

iex> Enum.min([5, 3, 0, -1])
-1

max

Функция max находит максимальное значение в коллекции:

iex> Enum.max([5, 3, 0, -1])
5

reduce

С помощью функции reduce можно объединить все элементы коллекции в единое значение. Для этого можно передать опциональное значение-аккумулятор. Если аккумулятор не передан, используется первое значение:

iex> Enum.reduce([1, 2, 3], 10, fn(x, acc) -> x + acc end)
16
iex> Enum.reduce([1, 2, 3], fn(x, acc) -> x + acc end)
6
iex> Enum.reduce(["a","b","c"], "1", fn(x,acc)-> x <> acc end)
"cba1"

sort

Сортировка коллекций реализуется не одной, а двумя функциями sort. Первая использует встроенный в язык механизм сравнения:

iex> Enum.sort([5, 6, 1, 3, -1, 4])
[-1, 1, 3, 4, 5, 6]

iex> Enum.sort([:foo, "bar", Enum, -1, 4])
[-1, 4, Enum, :foo, "bar"]

Вторая позволяет передать собственную функцию для сравнения элементов:

# с нашей функцией
iex> Enum.sort([%{:val => 4}, %{:val => 1}], fn(x, y) -> x[:val] > y[:val] end)
[%{val: 4}, %{val: 1}]

# без неё
iex> Enum.sort([%{:count => 4}, %{:count => 1}])
[%{count: 1}, %{count: 4}]

uniq

Для удаления дубликатов из коллекции используется функция uniq:

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

Поделиться