View Source Iter.Impl (iterex v0.1.1)
The default implementations of all Iter.Iterable
callbacks except next/1
.
By adding use Iter.Impl
to your Iter.Iterable
definition all of the
default functions will be automatically delegated and marked as overridable.
This allows you to implement only those callbacks which can reasonably be made faster for your particular iterable, and not have to implement all of them.
For example, here's a fictional implementation of iterable for List
:
defimpl Iter.Iterable, for: List do
use Iter.Impl
def next([head | tail]), do: {:ok, head, tail}
def next([]), do: :done
def peek([]), do: :done
def peek([head | _] = list), do: {:ok, head, list}
def empty?([]), do: true
def empty?(_), do: false
end
Be aware that all the default implementations rely on your implementation of
next/1
which you always must provide.
Summary
Functions
Generate overridable delegations to the default iterable callbacks.
Tests if every element in the iterable matches predicate
.
Tests if any element in the iterable matches predicate
.
Creates an iterable that appends an element to the end of the iterable.
Returns the element index
items from the beginning of the iterable.
Creates an iterable that chunks elements by subsequent return values of fun
.
Creates an iterable that chunks elements into count
sized chunks of step
spacing.
Creates an iterable that chunks based on a chunk function.
Takes an iterable and iterates each iterable in an iterable.
Consumes the iterable, returning the number of elements within
Consumes the iterable, returning the number of elements for which fun
returns a truthy value.
Creates an iterator that cycles it's elements eternally.
Creates an iterable that only emits elements if they are different from the previous element.
Creates an iterable that only emits elements if they are different from the previous element.
Creates an iterable which drops the first how_many
elements.
Returns a new iterable with every nth
element in the iterable
dropped,
starting with the first element.
Drops elements at the beginning of iterable
while fun returns a truthy
value.
Consumes the iterable and applies fun
to each element.
Determines if the iterable is empty.
Creates an iterable which drops elements for which predicate
doesn't return true.
Searches for the first element in the iterable which matches predicate
.
Returns the index of the first element in the iterable which matches predicate
.
Returns the first truthy value returned by fun
.
Creates an iterable which works like map/2
but flattens nested iterables.
Creates an iterable which flattens nested iterables.
Creates a new iterable which places separator
between adjacent items of the original iterable.
Creates a new iterable which applies mapper
to each element and using it's
result as the new element value.
Creates a new iterable which applies mapper
on every nth
element of the
iterable, starting with the first element.
Returns the maximal element in the iterable
according to Erlang's term ordering.
Returns the maximal element in the iterable
as calculated by mapper
.
Is the element a member of the iterable?
Returns the minimal element in the iterable
according to Erlang's term ordering.
Returns the minimal element in the iterable
as calculated by mapper
.
Finds the minimal and maximal elements in the iterable.
Peeks at the first element of the iterable, without consuming it.
Peeks at the first how_many
elements of the iterable, without consuming them.
Creates a new iterable which places element
at the beginning of the iterable.
Creates an iterable starting at the same point, but stepping by how_many
each iteration.
Collects the first how_many
elements into a new iterable and returns it
along with the advanced initial iterable.
Creates an iterable which takes the first how_many
elements.
Creates an iterable which takes the last how_many
elements.
Creates an iterable which emits elements until predicate
returns false
.
Convert the iterable into a list.
Creates an iterable that only emits unique elements.
Creates an iterable which emits the current iteration count as well as the next value.
Zips corresponding elements from a finite collection of iterables into one iterable of results as computed by zipper
.
Types
@type element() :: Iter.Iterable.element()
@type iterable() :: Iter.Iterable.t()
@type predicate() :: Iter.Iterable.predicate()
Functions
Generate overridable delegations to the default iterable callbacks.
Tests if every element in the iterable matches predicate
.
Examples
iex> Impl.all?([2, 4, 6, 8], &(rem(&1, 2) == 0))
true
iex> Impl.all?([2, 3, 4], &(rem(&1, 2) == 0))
false
Tests if any element in the iterable matches predicate
.
Examples
iex> Impl.any?([2, 4, 6], &(rem(&1, 2) == 1))
false
iex> Impl.any?([2, 3, 4], &(rem(&1, 2) == 1))
true
Creates an iterable that appends an element to the end of the iterable.
Examples
iex> Impl.append(1..3, 4)
...> |> Impl.to_list()
[1, 2, 3, 4]
@spec at(iterable(), non_neg_integer()) :: {:ok, element(), iterable()} | :done
Returns the element index
items from the beginning of the iterable.
Example
iex> Impl.at([:a, :b, :c], 1)
{:ok, :b, [:c]}
Creates an iterable that chunks elements by subsequent return values of fun
.
Example
iex> Impl.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1))
...> |> Impl.to_list()
[[1], [2, 2], [3], [4, 4, 6], [7, 7]]
@spec chunk_every(iterable(), pos_integer(), pos_integer(), iterable() | :discard) :: iterable()
Creates an iterable that chunks elements into count
sized chunks of step
spacing.
Examples
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 2, 2, []) |> Impl.to_list()
[[1, 2], [3, 4], [5, 6]]
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard) |> Impl.to_list()
[[1, 2, 3], [3, 4, 5]]
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7]) |> Impl.to_list()
[[1, 2, 3], [3, 4, 5], [5, 6, 7]]
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 3, 3, []) |> Impl.to_list()
[[1, 2, 3], [4, 5, 6]]
iex> cycler = Impl.cycle([0])
iex> Impl.chunk_every([1, 2, 3, 4], 3, 3, cycler) |> Impl.to_list()
[[1, 2, 3], [4, 0, 0]]
@spec chunk_while( iterable(), acc, (element(), acc -> {:cont, chunk, acc} | {:cont, acc} | {:halt, acc}), (acc -> {:cont, chunk, acc} | {:cont, acc}) ) :: iterable() when acc: any(), chunk: any()
Creates an iterable that chunks based on a chunk function.
Examples
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> iter = 1..10 |> Impl.chunk_while([], chunk_fun, after_fun)
iex> Impl.to_list(iter)
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
Takes an iterable and iterates each iterable in an iterable.
Example
iex> Impl.concat([1..3, 2..4, 3..5]) |> Impl.to_list()
[1, 2, 3, 2, 3, 4, 3, 4, 5]
@spec count(iterable()) :: non_neg_integer()
Consumes the iterable, returning the number of elements within
Examples
iex> Impl.count([])
0
iex> Impl.count([1,2,3])
3
@spec count(iterable(), (element() -> as_boolean(any()))) :: non_neg_integer()
Consumes the iterable, returning the number of elements for which fun
returns a truthy value.
Example
iex> 1..5
...> |> Impl.count(&(rem(&1, 2) == 0))
2
Creates an iterator that cycles it's elements eternally.
Example
iex> Impl.cycle(1..3)
...> |> Impl.take_head(5)
...> |> Impl.to_list()
[1, 2, 3, 1, 2]
Creates an iterable that only emits elements if they are different from the previous element.
Example
iex> Impl.dedup([:a, :a, :b, :c, :b, :c, :c, :d])
...> |> Impl.to_list()
[:a, :b, :c, :b, :c, :d]
Creates an iterable that only emits elements if they are different from the previous element.
The function fun
maps every element to a term which is used to determine if two elements are duplicates.
Example
iex> [{1, :a}, {2, :b}, {2, :c}, {1, :a}]
...> |> Impl.dedup_by(&elem(&1, 0))
...> |> Impl.to_list()
[{1, :a}, {2, :b}, {1, :a}]
@spec drop(iterable(), non_neg_integer()) :: iterable()
Creates an iterable which drops the first how_many
elements.
Examples
iex> Impl.drop([1, 2, 3], 2)
...> |> Impl.to_list()
[3]
iex> Impl.drop([1, 2, 3], 0)
...> |> Impl.to_list()
[1, 2, 3]
iex> Impl.drop([1, 2, 3], -2)
...> |> Impl.to_list()
[1]
@spec drop_every(iterable(), non_neg_integer()) :: iterable()
Returns a new iterable with every nth
element in the iterable
dropped,
starting with the first element.
Examples
iex> 1..10
...> |> Impl.drop_every(2)
...> |> Impl.to_list()
[2, 4, 6, 8, 10]
iex> 1..12
...> |> Impl.drop_every(3)
...> |> Impl.to_list()
[2, 3, 5, 6, 8, 9, 11, 12]
iex> 1..10
...> |> Impl.drop_every(0)
...> |> Impl.to_list()
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
iex> [1, 2, 3]
...> |> Impl.drop_every(1)
...> |> Impl.to_list()
[]
Drops elements at the beginning of iterable
while fun returns a truthy
value.
Example
iex> [1, 2, 3, 2, 1]
...> |> Impl.drop_while(&(&1 < 3))
...> |> Impl.to_list()
[3, 2, 1]
Consumes the iterable and applies fun
to each element.
Primarily used for side-effects.
Always returns :done
.
Example
Impl.each([1, 2, 3], &IO.puts("#{&1}"))
"1"
"2"
"3"
#=> :done
Determines if the iterable is empty.
Example
iex> Impl.empty?([])
true
iex> Impl.empty?(1..20)
false
Creates an iterable which drops elements for which predicate
doesn't return true.
Example
iex> Impl.filter([1, 2, 3, 4], &(rem(&1, 2) == 1))
...> |> Impl.to_list()
[1, 3]
Searches for the first element in the iterable which matches predicate
.
Example
iex> Impl.find([1, 2, 3, 4], &(&1 > 2))
{:ok, 3, [4]}
iex> Impl.find([1, 2, 3, 4], &(&1 > 4))
:done
@spec find_index(iterable(), predicate()) :: {:ok, non_neg_integer(), iterable()} | :done
Returns the index of the first element in the iterable which matches predicate
.
Examples
iex> Impl.find_index([1, 2, 3, 4], &(&1 > 2))
{:ok, 2, [4]}
iex> Impl.find_index([1, 2, 3, 4], &(&1 > 4))
:done
@spec find_value(iterable(), (element() -> result)) :: {:ok, result, iterable()} | :done when result: any()
Returns the first truthy value returned by fun
.
Example
iex> Impl.find_value([1, 2, 3, 4], fn
...> i when i > 2 -> i * 2
...> _ -> nil
...> end)
{:ok, 6, [4]}
Creates an iterable which works like map/2
but flattens nested iterables.
Example
iex> [:a, :b, :c]
...> |> Impl.flat_map(&[&1, &1])
...> |> Impl.to_list()
[:a, :a, :b, :b, :c, :c]
Creates an iterable which flattens nested iterables.
Example
iex> Impl.flatten([[1, 2], [3, [4, [5, 6]]]])
...> |> Impl.to_list()
[1, 2, 3, 4, 5, 6]
Creates a new iterable which places separator
between adjacent items of the original iterable.
Example
iex> Impl.intersperse([:a, :b, :c], :wat)
...> |> Impl.to_list()
[:a, :wat, :b, :wat, :c]
Creates a new iterable which applies mapper
to each element and using it's
result as the new element value.
Example
iex> Impl.map([1, 2, 3], &(&1 * &1))
...> |> Impl.to_list()
[1, 4, 9]
@spec map_every(iterable(), non_neg_integer(), (element() -> new_element)) :: iterable() when new_element: any()
Creates a new iterable which applies mapper
on every nth
element of the
iterable, starting with the first element.
The first element is always mapped unless nth
is 0
.
Examples
iex> Impl.map_every(1..10, 2, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1001, 2, 1003, 4, 1005, 6, 1007, 8, 1009, 10]
iex> Impl.map_every(1..10, 3, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1001, 2, 3, 1004, 5, 6, 1007, 8, 9, 1010]
iex> Impl.map_every(1..5, 0, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1, 2, 3, 4, 5]
iex> Impl.map_every([1, 2, 3], 1, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1001, 1002, 1003]
Returns the maximal element in the iterable
according to Erlang's term ordering.
Examples
iex> Impl.max([1, 3, 2], &>=/2)
{:ok, 3}
iex> Impl.max([], &>=/2)
:done
@spec max_by( iterable(), (element() -> new_element), (new_element, new_element -> boolean()) ) :: {:ok, element()} | :done when new_element: element()
Returns the maximal element in the iterable
as calculated by mapper
.
Example
iex> Impl.max_by(["a", "aa", "aaa"], &String.length/1, &>=/2)
{:ok, "aaa"}
iex> Impl.max_by([], &String.length/1, &>=/2)
:done
Is the element a member of the iterable?
Returns the minimal element in the iterable
according to Erlang's term ordering.
Examples
iex> Impl.min([1, 3, 2], &<=/2)
{:ok, 1}
iex> Impl.min([], &<=/2)
:done
@spec min_by( iterable(), (element() -> new_element), (new_element, new_element -> boolean()) ) :: {:ok, element()} | :done when new_element: element()
Returns the minimal element in the iterable
as calculated by mapper
.
Example
iex> Impl.min_by(["a", "aa", "aaa"], &String.length/1, &<=/2)
{:ok, "a"}
iex> Impl.min_by([], &String.length/1, &<=/2)
:done
Finds the minimal and maximal elements in the iterable.
Example
iex> Impl.min_max(1..12)
{:ok, 1, 12}
iex> Impl.min_max([])
:done
Peeks at the first element of the iterable, without consuming it.
Warning
Many iterables cannot be peeked, so this function simulates peeking by consuming an element from the iterable and returning a new iterable which pushes that element back on to the front.
Example
iex> {:ok, :a, iterable} = Impl.peek([:a, :b, :c])
...> Impl.to_list(iterable)
[:a, :b, :c]
@spec peek(iterable(), how_many :: pos_integer()) :: {:ok, [element()], non_neg_integer(), iterable()} | :done
Peeks at the first how_many
elements of the iterable, without consuming them.
Warning
Many iterables cannot be peeked, so this function simulates peeking by consuming elements from the iterable and returning a new iterable which pushes those elements back on to the front.
Example
iex> {:ok, [:a, :b, :c], 3, iterable} = Impl.peek([:a, :b, :c, :d], 3)
...> Impl.to_list(iterable)
[:a, :b, :c, :d]
Creates a new iterable which places element
at the beginning of the iterable.
Example
iex> 1..5
...> |> Impl.prepend(6)
...> |> Impl.to_list()
[6, 1, 2, 3, 4, 5]
@spec step_by(iterable(), non_neg_integer()) :: iterable()
Creates an iterable starting at the same point, but stepping by how_many
each iteration.
Example
iex> [0, 1, 2, 3, 4, 5]
...> |> Impl.step_by(2)
...> |> Impl.to_list()
[0, 2, 4]
@spec take_chunk(iterable(), pos_integer()) :: {:ok, iterable(), iterable()} | {:done, iterable()}
Collects the first how_many
elements into a new iterable and returns it
along with the advanced initial iterable.
This is very much like take/2
except that it returns the remaining iterable
so that it can be called repeatedly.
Example
iex> iter = 1..9
...> {:ok, [1, 2, 3], iter} = Impl.take_chunk(iter, 3)
...> {:ok, [4, 5, 6], iter} = Impl.take_chunk(iter, 3)
...> Impl.to_list(iter)
[7, 8, 9]
@spec take_head(iterable(), non_neg_integer()) :: iterable()
Creates an iterable which takes the first how_many
elements.
Example
iex> Impl.take_head(1..5, 0)
...> |> Impl.to_list()
[]
iex> Impl.take_head(1..5, 3)
...> |> Impl.to_list()
[1, 2, 3]
@spec take_tail(iterable(), non_neg_integer()) :: iterable()
Creates an iterable which takes the last how_many
elements.
Example
iex> Impl.take_tail(1..5, 0)
...> |> Impl.to_list()
[]
iex> Impl.take_tail(1..5, 3)
...> |> Impl.to_list()
[3, 4, 5]
Creates an iterable which emits elements until predicate
returns false
.
Example
iex> [1, 2, 3]
...> |> Impl.take_while(&(&1 < 3))
...> |> Impl.to_list()
[1, 2]
Convert the iterable into a list.
Creates an iterable that only emits unique elements.
Example
iex> Impl.uniq([:a, :a, :b, :c, :b, :c, :c, :d])
...> |> Impl.to_list()
[:a, :b, :c, :d]
Creates an iterable which emits the current iteration count as well as the next value.
This is analogous to Enum.with_index/1
except that counting starts from the
beginning of the iterable, meaning you can convert an iterable into an
enumerator after consuming some if it.
Examples
iex> Impl.with_index([:a, :b, :c]) ...> |> Impl.to_list() [a: 0, b: 1, c: 2]
iex> [:a, :b, :c, :d] ...> |> Impl.drop(2) ...> |> Impl.with_index() ...> |> Impl.to_list() [c: 0, d: 1]
Zips corresponding elements from a finite collection of iterables into one iterable of results as computed by zipper
.
Example
iex> Impl.zip([1..3, 4..6, 7..9], &List.to_tuple/1) ...> |> Impl.to_list() [{1, 4, 7}, {2, 5, 8}, {3, 6, 9}]