View Source Iter (Iter v0.1.2)
A blazing fast compile-time optimized alternative to the Enum
and Stream
modules.
overview
Overview
Iter
allows you to effortlessly write highly-efficient pipelines to process
enumerables, in a familiar and highly readable style.
iex> require Iter
iex> 1..10 |> Iter.map(& &1 ** 2) |> Iter.sum()
385
Iter
will merge both the map
and sum
steps and perform both in one single
pass. Unlike the same pipeline written with Enum
, it won't build any
intermediate list, therefore saving memory and CPU cycles.
You can think of Iter
as compile-time streams, or as comprehensions on
steroids. It should be highly efficient compared to the same pipeline written
with Stream
, since it does most of the work at compile time without any
runtime overhead. And while it actually works very similarly to for/1
under
the hood and basically emits the same code, it offers a much more flexible,
composable and extensive API.
The benchmarks
folder illustrates how Iter
compares to Enum
or Stream
through some examples.
Because Iter
is compile-time, these are macros and not functions. This has
several implications:
- you have to
require
the module first before using it - they won't appear in the stacktrace in case of errors (but
Iter
tries to make sure that stacktraces will point to the line of the step responsible) - if you "break" the pipeline,
Iter
won't be able to optimize it as a single pass: it will suffer the same issue asEnum
1..10
|> Iter.map(& &1 ** 2)
|> IO.inspect() # <= pipeline broken, creates an intermediate list
|> Iter.sum()
When there is no possibility of merging steps, Iter
is simply delegating to
Enum
which is optimized plenty on individual steps.
consistency
Consistency
Iter
is mostly consistent with the standard library, but it is prioritizing
efficiency over absolute consistency with the Enum
and Stream
modules, which
implies some slight differences. These differences are always documented in the
concerned macro docs.
negative-indexes
Negative indexes
Iter
only supports positive indexes when inside a pipeline, so most of
functions like at/1
, slice/1
or take/1
which would also accept negative
indexes cannot be replaced in cases needing it. The reason is simple: working
with negative indexes implies to materialize the whole list once. If you need
it, you should replace the relevant step to use Enum
, or maybe call
Iter.reverse/1
before accessing it (see
Collecting the pipeline section).
api-differences
API differences
Iter
should cover most of the Enum
API, but:
- some operations are still missing
- some operations won't be added because cannot be implemented efficiently
- some extra functions are being provided:
Iter.mean/1
,Iter.first/1
,Iter.last/1
(to compensate with the lack of negative indexes) andIter.match/3
(pattern-match to filter and extract at once, like in comprehensions)
collecting-the-pipeline
Collecting the pipeline
Some operations like Iter.to_list/1
, Iter.reverse/2
, Iter.reduce/3
,
Iter.group_by/2
... need to materialize an intermediate list or accumulator and
will collect the pipeline.
Operations that are collecting the pipeline are always mentioning it in their documentation.
Here is a simple example:
users
|> Iter.map(&fetch_user/1)
|> Iter.reject(&is_nil/1)
|> Iter.each(&process_user/1)
The pipeline above will start processing users as they are retrieved, in one
single pass. But assuming we want to make sure to be able to first retrieving
all users before starting the processing step, Iter.to_list/1
can be used to
make the intent explicit:
users
|> Iter.map(&fetch_user/1)
|> Iter.reject(&is_nil/1)
|> Iter.to_list() # forcing the pipeline to collect
|> Iter.each(&process_user/1)
Forcing a pipeline to collect through Enum.to_list/1
(or Enum.reverse/1
,
faster) can also be used to circumvent some of Iter
's limitations like the
absence of negative indexes support:
foo
|> Iter.map(&bar/1)
|> Iter.to_list() # forcing the pipeline to collect
|> Iter.take(maybe_negative_index)
In the example above, Iter.take/2
is now the only step of its pipeline and can
support negative indexing. The extra pass required is made explicit.
Link to this section Summary
Functions
Returns true
if all elements in enumerable
are truthy.
Equivalent to Enum.all?/1
.
Returns true
if fun
returns a truthy value for all elements in enumerable
.
Equivalent to Enum.all?/2
.
Returns true
if at least one element in enumerable
is truthy.
Equivalent to Enum.any?/1
.
Returns true
if fun
returns a truthy value for at least one element in enumerable
.
Equivalent to Enum.any?/2
.
Finds the element at the given index (zero-based). Equivalent to Enum.at/2
.
Finds the element at the given index (zero-based).
Equivalent to Enum.at/3
.
Given an enumerable
of enumerables, concatenates the enumerables into a single one.
Equivalent to Enum.concat/1
.
Concatenates the enumerable on the right
with the enumerable on the left
.
Equivalent to Enum.concat/2
.
Returns the size
of the enumerable. Equivalent to Enum.count/1
.
Returns the count of elements in the enumerable
for which fun
returns a truthy value.
Equivalent to Enum.count/2
.
Enumerates the enumerable
, removing successive duplicate elements.
Equivalent to Enum.dedup/1
.
Enumerates the enumerable
, removing successive elements for which fun
return duplicate values.
Equivalent to Enum.dedup_by/2
.
Drops an amount
of elements from the beginning of the enumerable
.
Equivalent to Enum.drop/2
.
Returns a list of every nth
element in the enumerable
dropped,
starting with the first element.
Equivalent to Enum.drop_every/2
.
Drops elements at the beginning of the enumerable
, while fun
returns
a truthy value. Equivalent to Enum.drop_while/2
.
Invokes the given fun
for each element in the enumerable
.
Equivalent to Enum.each/2
.
Returns true
if enumerable
is empty, otherwise false
.
Equivalent to Enum.empty?/1
.
Finds the element at the given index (zero-based).
Equivalent to Enum.fetch/2
.
Finds the element at the given index (zero-based).
Equivalent to Enum.fetch!/2
.
Filters the enumerable
, keeping only elements for which fun
returns a truthy value.
Equivalent to Enum.filter/2
.
Returns the first element for which fun
returns a truthy value.
Equivalent to Enum.find/2
.
Returns the first element for which fun
returns a truthy value,
returns default
if not found.any()
Equivalent to Enum.find/3
.
Similar to find/2
, but returns the index (zero-based) of the element
instead of the element itself.
Equivalent to Enum.find_index/2
.
Similar to find/2
, but returns the value of the function invocation instead
of the element itself. Equivalent to Enum.find_value/2
.
Similar to find/3
, but returns the value of the function invocation instead
of the element itself. Equivalent to Enum.find_value/3
.
Retrieves the first element of the enumerable
, or nil
if empty.
Retrieves the first element of the enumerable
, or default
if empty.
Maps the given fun
over enumerable
and flattens the result.
Equivalent to Enum.flat_map/2
.
Returns a map with keys as unique elements of enumerable
and values
as the count of every element.
Equivalent to Enum.frequencies/1
.
Returns a map with keys as unique elements given by key_fun
and values
as the count of every element.
Equivalent to Enum.frequencies_by/2
.
Splits the enumerable into groups based on key_fun
. Equivalent to Enum.group_by/2
.
Splits the enumerable into groups based on key_fun
.
Equivalent to Enum.group_by/3
.
Intersperses separator
between each element of the enumerable
.
Equivalent to Enum.intersperse/2
.
Inserts the given enumerable
into a collectable
.
Equivalent to Enum.into/2
.
Inserts the given enumerable
into a collectable
and maps the fun
function on each item.
Equivalent to Enum.into/3
.
Joins the given enumerable
into a string without any separator.
Equivalent to Enum.join/1
.
Joins the given enumerable
into a string with joiner
as a separator.
Equivalent to Enum.join/2
.
Retrieves the last element of the enumerable
, or nil
if empty.
Retrieves the last element of the enumerable
, or default
if empty.
Applies fun
on each element of enumerable
. Equivalent to Enum.map/2
.
Maps and intersperses the given enumerable
with separator
.
Equivalent to Enum.map_intersperse/3
.
Applies mapper
and joins the given enumerable
into a string without any separator.
Equivalent to Enum.map_join/2
.
Applies mapper
and joins the given enumerable
into a string with joiner
as a separator.
Equivalent to Enum.map_join/3
.
Invokes the given function to each element in the enumerable
to reduce it to
a single element, while keeping an accumulator.
Equivalent to Enum.map_reduce/3
.
Pattern-matches on each element of the enumerable
, filters out elements that
do not match the pattern
, and returns the expr
.
Returns the maximal element in the enumerable
according to Erlang's term ordering.
Equivalent to Enum.max/1
.
Returns the mean value of all elements in enumerable
.
Checks if element
exists within the enumerable
.
Equivalent to Enum.member?/2
.
Returns the minimal element in the enumerable
according to Erlang's term ordering.
Equivalent to Enum.min/1
.
Returns the product of all elements in enumerable
.
Equivalent to Enum.product/1
.
Returns a random element of the enumerable
. Equivalent to Enum.random/1
.
Invokes fun
for each element in the enumerable
with the accumulator.
Equivalent to Enum.reduce/2
.
Invokes fun
for each element in the enumerable
with the accumulator.
Equivalent to Enum.reduce/3
.
Filters the enumerable
, rejecting elements for which fun
returns a truthy value.
Equivalent to Enum.reject/2
.
Returns a list of elements in enumerable
in reverse order.
Equivalent to Enum.reverse/1
.
Reverses the elements in enumerable
, appends the tail
, and
returns the result as a list.
Equivalent to Enum.reverse/2
.
Applies the given function to each element in the enumerable
, storing the
result in a list and passing it as the accumulator for the next computation.
Equivalent to Enum.scan/3
.
Returns a list with enumerable
elements in a random order.
Equivalent to Enum.shuffle/1
.
Returns a subset list of the given enumerable
by index_range
.
Equivalent to Enum.slice/2
.
Returns a subset list of the given enumerable, from start_index
with amount
number of elements if available.
Equivalent to Enum.slice/3
.
Sorts the enumerable
according to Erlang's term ordering.
Equivalent to Enum.sort/1
.
Sorts the enumerable
by the given sorter
function or module.
Equivalent to Enum.sort/2
.
Sorts the mapped results of the enumerable
according to Erlang's term ordering.
Equivalent to Enum.sort_by/2
.
Splits the enumerable
into two lists, leaving amount
elements in the first one.
Equivalent to Enum.split/2
.
Splits the enumerable
in two at the position of the element for which fun
returns a falsy value for the first time. Equivalent to Enum.split_while/2
.
Splits the enumerable
in two lists based on the truthiness of applying fun
on
each element. Equivalent to Enum.split_with/2
.
Returns the sum of all elements in enumerable
. Equivalent to Enum.sum/1
.
Takes an amount
of elements from the beginning of the enumerable
.
Equivalent to Enum.take/2
.
Returns a list of every nth
element in the enumerable
, starting
with the first element.
Equivalent to Enum.take_every/2
.
Takes an amount
of random elements from the enumerable
.
Equivalent to Enum.take_random/2
.
Takes the elements from the beginning of the enumerable
, while fun
returns
a truthy value. Equivalent to Enum.take_while/2
.
Converts enumerable
to a list. Equivalent to Enum.to_list/1
.
Enumerates the enumerable
, removing the duplicate elements.
Equivalent to Enum.uniq/1
.
Enumerates the enumerable
, removing elements for which fun
return duplicate values.
Equivalent to Enum.uniq_by/2
.
Extracts two-element tuples from the given enumerable
and returns them
as two separate lists.
Equivalent to Enum.unzip/1
.
Returns the enumerable
with each element wrapped in a tuple
alongside its index. Equivalent to Enum.with_index/1
.
Returns the enumerable
with each element wrapped in a tuple
alongside its index. Equivalent to Enum.with_index/2
.
Zips corresponding elements from a finite collection of enumerables
into a list of tuples.
Zips corresponding elements from two enumerables into a list of tuples.
Link to this section Functions
Returns true
if all elements in enumerable
are truthy.
Equivalent to Enum.all?/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.all?(["yes", true])
true
iex> Iter.all?([false, true])
false
iex> Iter.all?([])
true
Returns true
if fun
returns a truthy value for all elements in enumerable
.
Equivalent to Enum.all?/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
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> Iter.all?([], fn x -> rem(x, 2) == 0 end)
true
Returns true
if at least one element in enumerable
is truthy.
Equivalent to Enum.any?/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.any?([false, true])
true
iex> Iter.any?([false, nil])
false
iex> Iter.any?([])
false
Returns true
if fun
returns a truthy value for at least one element in enumerable
.
Equivalent to Enum.any?/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
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> Iter.any?([], fn x -> rem(x, 2) == 1 end)
false
Finds the element at the given index (zero-based). Equivalent to Enum.at/2
.
Returns nil
if not found.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
Also, see Iter.last/1
if you need to access the last element.
examples
Examples
iex> Iter.at([:foo, :bar, :baz], 2)
:baz
iex> Iter.at([:foo, :bar, :baz], 3)
nil
Finds the element at the given index (zero-based).
Equivalent to Enum.at/3
.
Returns default
if not found.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.at(1..1000, 5, :none)
6
iex> Iter.at(1..1000, 1000, :none)
:none
Given an enumerable
of enumerables, concatenates the enumerables into a single one.
Equivalent to Enum.concat/1
.
examples
Examples
iex> Iter.concat([1..3, 4..6])
[1, 2, 3, 4, 5, 6]
Concatenates the enumerable on the right
with the enumerable on the left
.
Equivalent to Enum.concat/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.concat(1..3, 4..6)
[1, 2, 3, 4, 5, 6]
Returns the size
of the enumerable. Equivalent to Enum.count/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.count([1, 2, 3])
3
Returns the count of elements in the enumerable
for which fun
returns a truthy value.
Equivalent to Enum.count/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.count(1..5, fn x -> rem(x, 2) == 0 end)
2
Enumerates the enumerable
, removing successive duplicate elements.
Equivalent to Enum.dedup/1
.
examples
Examples
iex> Iter.dedup([1, 2, 2, 3, 3, 1, 3])
[1, 2, 3, 1, 3]
Enumerates the enumerable
, removing successive elements for which fun
return duplicate values.
Equivalent to Enum.dedup_by/2
.
examples
Examples
iex> Iter.dedup_by([{1, :a}, {2, :b}, {2, :c}, {1, :a}], fn {x, _} -> x end)
[{1, :a}, {2, :b}, {1, :a}]
Drops an amount
of elements from the beginning of the enumerable
.
Equivalent to Enum.drop/2
.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.drop(1..10, 5)
[6, 7, 8, 9, 10]
Returns a list of every nth
element in the enumerable
dropped,
starting with the first element.
Equivalent to Enum.drop_every/2
.
examples
Examples
iex> Iter.drop_every(1..10, 3)
[2, 3, 5, 6, 8, 9]
Drops elements at the beginning of the enumerable
, while fun
returns
a truthy value. Equivalent to Enum.drop_while/2
.
examples
Examples
iex> Iter.drop_while(1..10, & &1 < 6)
[6, 7, 8, 9, 10]
Invokes the given fun
for each element in the enumerable
.
Equivalent to Enum.each/2
.
Returns :ok
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> {:ok, pid} = Agent.start(fn -> [] end)
iex> Iter.each(1..5, fn i -> Agent.update(pid, &[i | &1]) end)
:ok
iex> Agent.get(pid, & &1)
[5, 4, 3, 2, 1]
Returns true
if enumerable
is empty, otherwise false
.
Equivalent to Enum.empty?/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.empty?([])
true
iex> Iter.empty?([:foo])
false
Finds the element at the given index (zero-based).
Equivalent to Enum.fetch/2
.
Returns {:ok, element}
if found, otherwise :error
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.fetch([:foo, :bar, :baz], 2)
{:ok, :baz}
iex> Iter.fetch([:foo, :bar, :baz], 3)
:error
Finds the element at the given index (zero-based).
Equivalent to Enum.fetch!/2
.
Raises OutOfBoundsError
if the given index is outside the range
of the enumerable
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.fetch!([:foo, :bar, :baz], 2)
:baz
iex> Iter.fetch!([:foo, :bar, :baz], 3)
** (Enum.OutOfBoundsError) out of bounds error
Filters the enumerable
, keeping only elements for which fun
returns a truthy value.
Equivalent to Enum.filter/2
.
examples
Examples
iex> Iter.filter(1..4, &rem(&1, 2) == 1)
[1, 3]
Returns the first element for which fun
returns a truthy value.
Equivalent to Enum.find/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.find([2, 3, 4], fn x -> rem(x, 2) == 1 end)
3
iex> Iter.find([2, 4, 6], fn x -> rem(x, 2) == 1 end)
nil
Returns the first element for which fun
returns a truthy value,
returns default
if not found.any()
Equivalent to Enum.find/3
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.find([2, 3, 4], 0, fn x -> rem(x, 2) == 1 end)
3
iex> Iter.find([2, 4, 6], 0, fn x -> rem(x, 2) == 1 end)
0
Similar to find/2
, but returns the index (zero-based) of the element
instead of the element itself.
Equivalent to Enum.find_index/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.find_index(["ant", "bat", "cat"], fn x -> x =~ "b" end)
1
iex> Iter.find_index(["ant", "bat", "cat"], fn x -> x =~ "z" end)
nil
Similar to find/2
, but returns the value of the function invocation instead
of the element itself. Equivalent to Enum.find_value/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.find_value([%{x: nil}, %{x: 5}, %{}], fn map -> map[:x] end)
5
iex> Iter.find_value([%{x: nil}, %{}, %{}], fn map -> map[:x] end)
nil
Similar to find/3
, but returns the value of the function invocation instead
of the element itself. Equivalent to Enum.find_value/3
.
Returns default
if not found.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.find_value([%{x: nil}, %{x: 5}, %{}], 0, fn map -> map[:x] end)
5
iex> Iter.find_value([%{x: nil}, %{}, %{}], 0, fn map -> map[:x] end)
0
Retrieves the first element of the enumerable
, or nil
if empty.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
There is no equivalent Enum
function.
examples
Examples
iex> Iter.first(1..1000)
1
iex> Iter.first([])
nil
Retrieves the first element of the enumerable
, or default
if empty.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
There is no equivalent Enum
function.
examples
Examples
iex> Iter.first(1..10, :none)
1
iex> Iter.first([], :none)
:none
Maps the given fun
over enumerable
and flattens the result.
Equivalent to Enum.flat_map/2
.
examples
Examples
iex> Iter.flat_map(1..3, fn n -> 1..n end)
[1, 1, 2, 1, 2, 3]
Returns a map with keys as unique elements of enumerable
and values
as the count of every element.
Equivalent to Enum.frequencies/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.frequencies([1, 1, 2, 1, 2, 3])
%{1 => 3, 2 => 2, 3 => 1}
Returns a map with keys as unique elements given by key_fun
and values
as the count of every element.
Equivalent to Enum.frequencies_by/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.frequencies_by(~w{aa aA bb cc}, &String.downcase/1)
%{"aa" => 2, "bb" => 1, "cc" => 1}
Splits the enumerable into groups based on key_fun
. Equivalent to Enum.group_by/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.group_by(~w{ant buffalo cat dingo}, &String.length/1)
%{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
Splits the enumerable into groups based on key_fun
.
Equivalent to Enum.group_by/3
.
The result is a map where each key is given by key_fun
and each
value is a list of elements given by value_fun
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1)
%{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]}
Intersperses separator
between each element of the enumerable
.
Equivalent to Enum.intersperse/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.intersperse(1..3, :foo)
[1, :foo, 2, :foo, 3]
Inserts the given enumerable
into a collectable
.
Equivalent to Enum.into/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.into([a: 1, b: 2, a: 3], %{})
%{a: 3, b: 2}
iex> Iter.into([1, 2, 1, 2.0], MapSet.new())
MapSet.new([1, 2, 2.0])
Inserts the given enumerable
into a collectable
and maps the fun
function on each item.
Equivalent to Enum.into/3
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.into([a: 1, b: 2, a: 3], %{}, fn {k, v} -> {k, v * 2} end)
%{a: 6, b: 4}
iex> Iter.into([1, 2, 1, 2.0], MapSet.new(), & &1 * 2)
MapSet.new([2, 4, 4.0])
Joins the given enumerable
into a string without any separator.
Equivalent to Enum.join/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.join(1..3)
"123"
Joins the given enumerable
into a string with joiner
as a separator.
Equivalent to Enum.join/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.join(1..3, "-")
"1-2-3"
Retrieves the last element of the enumerable
, or nil
if empty.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
There is no equivalent Enum
function, but it can compensate
for the lack of negative index support in at/2
.
examples
Examples
iex> Iter.last(1..10)
10
iex> Iter.last([])
nil
Retrieves the last element of the enumerable
, or default
if empty.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
There is no equivalent Enum
function, but it can compensate
for the lack of negative index support in at/3
.
examples
Examples
iex> Iter.last(1..10, :none)
10
iex> Iter.last([], :none)
:none
Applies fun
on each element of enumerable
. Equivalent to Enum.map/2
.
examples
Examples
iex> Iter.map(1..3, & &1 ** 2)
[1, 4, 9]
Maps and intersperses the given enumerable
with separator
.
Equivalent to Enum.map_intersperse/3
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.map_intersperse(1..3, :foo, & &1 ** 2)
[1, :foo, 4, :foo, 9]
Applies mapper
and joins the given enumerable
into a string without any separator.
Equivalent to Enum.map_join/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.map_join(1..3, & &1 ** 2)
"149"
Applies mapper
and joins the given enumerable
into a string with joiner
as a separator.
Equivalent to Enum.map_join/3
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.map_join(1..3, "-", & &1 ** 2)
"1-4-9"
Invokes the given function to each element in the enumerable
to reduce it to
a single element, while keeping an accumulator.
Equivalent to Enum.map_reduce/3
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.map_reduce([1, 2, 3], 0, fn x, acc -> {x * 2, x + acc} end)
{[2, 4, 6], 6}
Pattern-matches on each element of the enumerable
, filters out elements that
do not match the pattern
, and returns the expr
.
This works a bit like a combination of map/2
and filter/2
and works very
similarly as for/1
comprehensions.
There is no equivalent Enum
function.
examples
Examples
iex> Iter.match([{:ok, 1}, :error, {:ok, 3}], {:ok, x}, x + 1)
[2, 4]
The pattern also supports guards:
iex> Iter.match([1, nil, 3], x when is_integer(x), x * 2)
[2, 6]
Returns the maximal element in the enumerable
according to Erlang's term ordering.
Equivalent to Enum.max/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.max([2, 4, 1, 3])
4
iex> Iter.max([])
** (Enum.EmptyError) empty error
Returns the mean value of all elements in enumerable
.
Raises Enum.EmptyError
if enumerable
is empty.
There is no equivalent Enum
function.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.mean(1..10)
5.5
iex> Iter.mean([])
** (Enum.EmptyError) empty error
Checks if element
exists within the enumerable
.
Equivalent to Enum.member?/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Enum.member?([:ant, :bat, :cat], :bat)
true
iex> Enum.member?([:ant, :bat, :cat], :dog)
false
iex> Iter.member?([1, 2, 3], 2.0)
false
Returns the minimal element in the enumerable
according to Erlang's term ordering.
Equivalent to Enum.min/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.min([2, 4, 1, 3])
1
iex> Iter.min([])
** (Enum.EmptyError) empty error
Returns the product of all elements in enumerable
.
Equivalent to Enum.product/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.product(1..3)
6
Returns a random element of the enumerable
. Equivalent to Enum.random/1
.
Raises Enum.EmptyError
if enumerable
is empty.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exsss, {1, 2, 3})
iex> Iter.random(1..100)
27
Invokes fun
for each element in the enumerable
with the accumulator.
Equivalent to Enum.reduce/2
.
Raises Enum.EmptyError
if enumerable
is empty.
The first element of the enumerable
is used as the initial value of the accumulator.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.reduce(1..5, &*/2)
120
iex> Iter.reduce([], &*/2)
** (Enum.EmptyError) empty error
Invokes fun
for each element in the enumerable
with the accumulator.
Equivalent to Enum.reduce/3
.
The value of acc
is used as the initial value of the accumulator.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.reduce(1..5, 1, &*/2)
120
Filters the enumerable
, rejecting elements for which fun
returns a truthy value.
Equivalent to Enum.reject/2
.
examples
Examples
iex> Iter.reject(1..4, &rem(&1, 2) == 1)
[2, 4]
Returns a list of elements in enumerable
in reverse order.
Equivalent to Enum.reverse/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.reverse(1..3)
[3, 2, 1]
Reverses the elements in enumerable
, appends the tail
, and
returns the result as a list.
Equivalent to Enum.reverse/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.reverse(1..3, 4..6)
[3, 2, 1, 4, 5, 6]
Applies the given function to each element in the enumerable
, storing the
result in a list and passing it as the accumulator for the next computation.
Equivalent to Enum.scan/3
.
examples
Examples
iex> Iter.scan(1..5, 1, &*/2)
[1, 2, 6, 24, 120]
Returns a list with enumerable
elements in a random order.
Equivalent to Enum.shuffle/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exsss, {1, 2, 3})
iex> Iter.shuffle(1..6)
[3, 2, 5, 1, 4, 6]
Returns a subset list of the given enumerable
by index_range
.
Equivalent to Enum.slice/2
.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.slice(1..100, 5..15)
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
iex> Iter.slice(1..100, 5..15//5)
[6, 11, 16]
Returns a subset list of the given enumerable, from start_index
with amount
number of elements if available.
Equivalent to Enum.slice/3
.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.slice(1..100, 5, 10)
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Sorts the enumerable
according to Erlang's term ordering.
Equivalent to Enum.sort/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.sort([4, 1, 5, 2, 3])
[1, 2, 3, 4, 5]
Sorts the enumerable
by the given sorter
function or module.
Equivalent to Enum.sort/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.sort([4, 1, 5, 2, 3], :desc)
[5, 4, 3, 2, 1]
Sorts the mapped results of the enumerable
according to Erlang's term ordering.
Equivalent to Enum.sort_by/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
This is actually just an alias for Enum.sort_by/2
, Iter
isn't able to
optimize it.
examples
Examples
iex> Iter.sort_by(["some", "kind", "of", "monster"], &byte_size/1)
["of", "some", "kind", "monster"]
Splits the enumerable
into two lists, leaving amount
elements in the first one.
Equivalent to Enum.split/2
.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.split(1..10, 5)
{[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]}
Splits the enumerable
in two at the position of the element for which fun
returns a falsy value for the first time. Equivalent to Enum.split_while/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.split_while(1..10, & &1 < 6)
{[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]}
Splits the enumerable
in two lists based on the truthiness of applying fun
on
each element. Equivalent to Enum.split_with/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.split_with(1..4, &rem(&1, 2) == 1)
{[1, 3], [2, 4]}
Returns the sum of all elements in enumerable
. Equivalent to Enum.sum/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.sum(1..3)
6
Takes an amount
of elements from the beginning of the enumerable
.
Equivalent to Enum.take/2
.
Note: Negative indexes are NOT supported when used in a pipeline, since this
would imply to materialize the whole list and therefore cannot be done lazily.
If you need to use negative indexes, you can either use materialize the pipeline first
using Iter.to_list/1
or use the equivalent Enum
function.
Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.take(1..1000, 5)
[1, 2, 3, 4, 5]
Returns a list of every nth
element in the enumerable
, starting
with the first element.
Equivalent to Enum.take_every/2
.
examples
Examples
iex> Iter.take_every(1..10, 3)
[1, 4, 7, 10]
Takes an amount
of random elements from the enumerable
.
Equivalent to Enum.take_random/2
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
# Although not necessary, let's seed the random algorithm
iex> :rand.seed(:exsss, {1, 2, 3})
iex> Iter.take_random(1..100, 3)
[74, 28, 55]
Takes the elements from the beginning of the enumerable
, while fun
returns
a truthy value. Equivalent to Enum.take_while/2
.
examples
Examples
iex> Iter.take_while(1..1000, & &1 < 6)
[1, 2, 3, 4, 5]
Converts enumerable
to a list. Equivalent to Enum.to_list/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.to_list(1..3)
[1, 2, 3]
Enumerates the enumerable
, removing the duplicate elements.
Equivalent to Enum.uniq/1
.
examples
Examples
iex> Iter.uniq([1, 2, 1, 3, 2, 4])
[1, 2, 3, 4]
Enumerates the enumerable
, removing elements for which fun
return duplicate values.
Equivalent to Enum.uniq_by/2
.
examples
Examples
iex> Iter.uniq_by([{1, :x}, {2, :y}, {1, :z}], fn {x, _} -> x end)
[{1, :x}, {2, :y}]
Extracts two-element tuples from the given enumerable
and returns them
as two separate lists.
Equivalent to Enum.unzip/1
.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.unzip([{:a, 1}, {:b, 2}, {:c, 3}])
{[:a, :b, :c], [1, 2, 3]}
Returns the enumerable
with each element wrapped in a tuple
alongside its index. Equivalent to Enum.with_index/1
.
examples
Examples
iex> Iter.with_index(["a", "b", "c"])
[{"a", 0}, {"b", 1}, {"c", 2}]
Returns the enumerable
with each element wrapped in a tuple
alongside its index. Equivalent to Enum.with_index/2
.
Like Enum.with_index/2
, accepts either an anonymous function or an integer offset,
but it has to infer the type at compile time. If the expression can't be inferred to
be either an fn
or a capture, it will assume it is an integer
(example: Iter.with_index(list, var)
will only work if var
is an integer).
If an offset is given, it will index from the given offset instead of from zero.
If a function is given, it will index by invoking the function for each element
and index (zero-based) of the enumerable
.
examples
Examples
iex> Iter.with_index(["a", "b", "c"], 100)
[{"a", 100}, {"b", 101}, {"c", 102}]
iex> Iter.with_index(["a", "b", "c"], fn elem, index -> String.duplicate(elem, index) end)
["", "b", "cc"]
iex> Iter.with_index(["a", "b", "c"], &String.duplicate(&1, &2))
["", "b", "cc"]
Zips corresponding elements from a finite collection of enumerables
into a list of tuples.
This is actually just an alias for Enum.zip/1
, Iter
isn't able to
optimize it.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.zip([[1, 2, 3], [:a, :b, :c], ["foo", "bar", "baz"]])
[{1, :a, "foo"}, {2, :b, "bar"}, {3, :c, "baz"}]
Zips corresponding elements from two enumerables into a list of tuples.
This is actually just an alias for Enum.zip/2
, Iter
isn't able to
optimize it.
Note: This step collects the pipeline and cannot be merged with following steps. Read the Collecting the pipeline section for more information.
examples
Examples
iex> Iter.zip([1, 2, 3, 4, 5], [:a, :b, :c])
[{1, :a}, {2, :b}, {3, :c}]