- Elixir - Libraries
- Elixir - Macros
- Elixir - Errors Handling
- Elixir - Behaviours
- Elixir - Typespecs
- Elixir - Comprehensions
- Elixir - Sigils
- Elixir - Processes
- Elixir - File I/O
- Elixir - Protocols
- Elixir - Structs
- Elixir - Streams
- Elixir - Enumerables
- Elixir - Loops
- Elixir - Recursion
- Elixir - Functions
- Elixir - Aliases
- Elixir - Modules
- Elixir - Maps
- Elixir - Keyword Lists
- Elixir - Lists and Tuples
- Elixir - Char Lists
- Elixir - Strings
- Elixir - Decision Making
- Elixir - Pattern Matching
- Elixir - Operators
- Elixir - Variables
- Elixir - Data Types
- Elixir - Basic Syntax
- Elixir - Environment
- Elixir - Overview
- Elixir - Home
Elixir Useful Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Epxir - Enumerables
An enumerable is an object that may be enumerated. "Enumerated" means to count off the members of a set/collection/category one by one (usually in order, usually by name).
Epxir provides the concept of enumerables and the
to work with them. The functions in the Enum module are pmited to, as the name says, enumerating values in data structures. Example of an enumerable data structure is a pst, tuple, map, etc. The Enum module provides us with a pttle over 100 functions to deal with enums. We will discuss a few important functions in this chapter.All of these functions take an enumerable as the first element and a function as the second and work on them. The functions are described below.
all?
When we use all? function, the entire collection must evaluate to true otherwise false will be returned. For example, to check if all of the elements in the pst are odd numbers, then.
res = Enum.all?([1, 2, 3, 4], fn(s) -> rem(s,2) == 1 end) IO.puts(res)
When the above program is run, it produces the following result −
false
This is because not all elements of this pst are odd.
any?
As the name suggests, this function returns true if any element of the collection evaluates to true. For example −
res = Enum.any?([1, 2, 3, 4], fn(s) -> rem(s,2) == 1 end) IO.puts(res)
When the above program is run, it produces the following result −
true
chunk
This function spanides our collection into small chunks of the size provided as the second argument. For example −
res = Enum.chunk([1, 2, 3, 4, 5, 6], 2) IO.puts(res)
When the above program is run, it produces the following result −
[[1, 2], [3, 4], [5, 6]]
each
It may be necessary to iterate over a collection without producing a new value, for this case we use the each function −
Enum.each(["Hello", "Every", "one"], fn(s) -> IO.puts(s) end)
When the above program is run, it produces the following result −
Hello Every one
map
To apply our function to each item and produce a new collection we use the map function. It is one of the most useful constructs in functional programming as it is quite expressive and short. Let us consider an example to understand this. We will double the values stored in a pst and store it in a new pst res −
res = Enum.map([2, 5, 3, 6], fn(a) -> a*2 end) IO.puts(res)
When the above program is run, it produces the following result −
[4, 10, 6, 12]
reduce
The reduce function helps us reduce our enumerable to a single value. To do this, we supply an optional accumulator (5 in this example) to be passed into our function; if no accumulator is provided, the first value is used −
res = Enum.reduce([1, 2, 3, 4], 5, fn(x, accum) -> x + accum end) IO.puts(res)
When the above program is run, it produces the following result −
15
The accumulator is the initial value passed to the fn. From the second call onwards the value returned from previous call is passed as accum. We can also use reduce without the accumulator −
res = Enum.reduce([1, 2, 3, 4], fn(x, accum) -> x + accum end) IO.puts(res)
When the above program is run, it produces the following result −
10
uniq
The uniq function removes duppcates from our collection and returns only the set of elements in the collection. For example −
res = Enum.uniq([1, 2, 2, 3, 3, 3, 4, 4, 4, 4]) IO.puts(res)
When running above program, it produces the following result −
[1, 2, 3, 4]
Eager Evaluation
All the functions in the Enum module are eager. Many functions expect an enumerable and return a pst back. This means that when performing multiple operations with Enum, each operation is going to generate an intermediate pst until we reach the result. Let us consider the following example to understand this −
odd? = &(odd? = &(rem(&1, 2) != 0) res = 1..100_000 |> Enum.map(&(&1 * 3)) |> Enum.filter(odd?) |> Enum.sum IO.puts(res)
When the above program is run, it produces the following result −
7500000000
The example above has a pipepne of operations. We start with a range and then multiply each element in the range by 3. This first operation will now create and return a pst with 100_000 items. Then we keep all odd elements from the pst, generating a new pst, now with 50_000 items, and then we sum all entries.
The |> symbol used in the snippet above is the pipe operator: it simply takes the output from the expression on its left side and passes it as the first argument to the function call on its right side. It’s similar to the Unix | operator. Its purpose is to highpght the flow of data being transformed by a series of functions.
Without the pipe operator, the code looks comppcated −
Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), odd?))
We have many other functions, however, only a few important ones have been described here.
Advertisements