Учебники

Эликсир — перечислимые

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

Elixir предлагает концепцию перечислимых элементов и модуль Enum для работы с ними. Функции в модуле Enum ограничены, как следует из названия, перечислением значений в структурах данных. Примером перечислимой структуры данных является список, кортеж, карта и т. Д. Модуль Enum предоставляет нам чуть более 100 функций для работы с перечислениями. Мы обсудим несколько важных функций в этой главе.

Все эти функции принимают перечислимый в качестве первого элемента и функцию в качестве второго и работают с ними. Функции описаны ниже.

все?

Когда мы используем все ? функция, вся коллекция должна иметь значение true, в противном случае будет возвращено значение false. Например, чтобы проверить, являются ли все элементы в списке нечетными числами, тогда.

Live Demo

res = Enum.all?([1, 2, 3, 4], fn(s) -> rem(s,2) == 1 end) 
IO.puts(res)

Когда вышеуказанная программа запущена, она дает следующий результат —

false

Это потому, что не все элементы этого списка нечетны.

любой?

Как следует из названия, эта функция возвращает true, если какой-либо элемент коллекции оценивается как true. Например —

Live Demo

res = Enum.any?([1, 2, 3, 4], fn(s) -> rem(s,2) == 1 end)
IO.puts(res)

Когда вышеуказанная программа запущена, она дает следующий результат —

true

ломоть

Эта функция делит нашу коллекцию на маленькие порции размера, указанного в качестве второго аргумента. Например —

res = Enum.chunk([1, 2, 3, 4, 5, 6], 2)
IO.puts(res)

Когда вышеуказанная программа запущена, она дает следующий результат —

[[1, 2], [3, 4], [5, 6]]

каждый

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

Live Demo

Enum.each(["Hello", "Every", "one"], fn(s) -> IO.puts(s) end)

Когда вышеуказанная программа запущена, она дает следующий результат —

Hello
Every
one

карта

Чтобы применить нашу функцию к каждому элементу и создать новую коллекцию, мы используем функцию карты. Это одна из самых полезных конструкций в функциональном программировании, так как она довольно выразительна и коротка. Давайте рассмотрим пример, чтобы понять это. Мы удвоим значения, хранящиеся в списке, и сохраним их в новом списке —

res = Enum.map([2, 5, 3, 6], fn(a) -> a*2 end)
IO.puts(res)

Когда вышеуказанная программа запущена, она дает следующий результат —

[4, 10, 6, 12]

уменьшить

Функция Reduce помогает нам уменьшить наше перечисляемое значение до единственного значения. Для этого мы поставляем дополнительный аккумулятор (в нашем примере 5) для передачи в нашу функцию; если аккумулятор не указан, используется первое значение —

Live Demo

res = Enum.reduce([1, 2, 3, 4], 5, fn(x, accum) -> x + accum end)
IO.puts(res)

Когда вышеуказанная программа запущена, она дает следующий результат —

15

Аккумулятор — это начальное значение, передаваемое в fn . Начиная со второго вызова, значение, возвращаемое предыдущим вызовом, передается как накопленный. Мы также можем использовать уменьшить без аккумулятора —

Live Demo

res = Enum.reduce([1, 2, 3, 4], fn(x, accum) -> x + accum end)
IO.puts(res)

Когда вышеуказанная программа запущена, она дает следующий результат —

10

уник

Функция uniq удаляет дубликаты из нашей коллекции и возвращает только набор элементов в коллекции. Например —

res = Enum.uniq([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
IO.puts(res)

При запуске вышеуказанной программы, она дает следующий результат —

[1, 2, 3, 4]

Стремительная оценка

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

odd? = &(odd? = &(rem(&1, 2) != 0) 
res = 1..100_000 |> Enum.map(&(&1 * 3)) |> Enum.filter(odd?) |> Enum.sum 
IO.puts(res) 

Когда вышеуказанная программа запущена, она дает следующий результат —

7500000000

В приведенном выше примере есть конвейер операций. Мы начнем с диапазона, а затем умножим каждый элемент в диапазоне на 3. Эта первая операция теперь создаст и вернет список из 100_000 элементов. Затем мы сохраняем все нечетные элементы из списка, генерируя новый список, теперь с 50_000 элементами, а затем суммируем все записи.

Символ |>, используемый в приведенном выше фрагменте, является оператором канала : он просто берет вывод из выражения с левой стороны и передает его в качестве первого аргумента в вызов функции с правой стороны. Это похоже на Unix | оператор. Его цель состоит в том, чтобы выделить поток данных, преобразуемых с помощью ряда функций.

Без оператора канала код выглядит сложным —

Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), odd?))

У нас есть много других функций, однако, только несколько важных были описаны здесь.