View Source Bunch.Enum (Bunch v1.6.1)
A bunch of helper functions for manipulating enums.
Summary
Functions
Splits enumerable into chunks, and passes each chunk through collector
.
Returns elements that occur at least min_occurences
times in enumerable.
Generates a list by calling i
times function f
.
Generates a list consisting of i
values v
.
Works like Enum.each/2
, but breaks on error.
Works like Enum.flat_map/2
, but breaks on error.
Works like Enum.each/2
, but breaks on error.
Works like Enum.map/2
, but breaks on error.
Works like Enum.map_reduce/3
, but breaks on error.
Works like Enum.reduce/3
, but breaks on error.
Works like Enum.reduce_while/3
, but breaks on error.
Implementation of Enum.unzip/1
for more-than-two-element tuples.
Works the same way as Enum.zip/1
, but does not cut off remaining values.
Functions
@spec chunk_by_prev(Enum.t(), chunker :: (a, a -> boolean()), collector :: ([a] -> b)) :: [b] when a: any(), b: any()
Splits enumerable into chunks, and passes each chunk through collector
.
New chunk is created each time chunker
returns false
. The chunker
is passed
current and previous element of enumerable.
Examples:
iex> Bunch.Enum.chunk_by_prev([1,2,5,5], fn x, y -> x - y <= 2 end)
[[1, 2], [5, 5]]
iex> Bunch.Enum.chunk_by_prev([1,2,5,5], fn x, y -> x - y <= 2 end, &Enum.sum/1)
[3, 10]
@spec duplicates(Enum.t(), pos_integer()) :: list()
Returns elements that occur at least min_occurences
times in enumerable.
Results are NOT ordered in any sensible way, neither is the order anyhow preserved, but it is deterministic.
Examples
iex> Bunch.Enum.duplicates([1,3,2,5,3,2,2])
[2, 3]
iex> Bunch.Enum.duplicates([1,3,2,5,3,2,2], 3)
[2]
@spec repeat(f :: (-> a), non_neg_integer()) :: [a] when a: any()
Generates a list by calling i
times function f
.
iex> {:ok, pid} = Agent.start_link(fn -> 0 end)
iex> Bunch.Enum.repeat(fn -> Agent.get_and_update(pid, &{&1, &1+1}) end, 4)
[0, 1, 2, 3]
iex> Bunch.Enum.repeat(fn -> :abc end, 0)
[]
@spec repeated(v, non_neg_integer()) :: [v] when v: any()
Generates a list consisting of i
values v
.
iex> Bunch.Enum.repeated(:abc, 4)
[:abc, :abc, :abc, :abc]
iex> Bunch.Enum.repeated(:abc, 0)
[]
@spec try_each(Enum.t(), fun :: (a -> result)) :: result when a: any(), result: Bunch.Type.try_t()
Works like Enum.each/2
, but breaks on error.
Behaves like Enum.each/2
as long as given fun
returns :ok
.
If it happens to return {:error, reason}
, traversal is stopped and the
error is returned.
Examples:
iex> fun = fn 0 -> {:error, :zero}; x -> send(self(), 1/x); :ok end
iex> Bunch.Enum.try_each([1,2,3], fun)
:ok
iex> Bunch.Enum.try_each([1,0,3], fun)
{:error, :zero}
@spec try_flat_map(Enum.t(), fun :: (a -> result)) :: result when a: any(), b: any(), result: Bunch.Type.try_t([b])
Works like Enum.flat_map/2
, but breaks on error.
Behaves like Enum.flat_map/2
as long as reducing function returns {:ok, values}
.
If it happens to return {:error, reason}
, reduction is stopped and the
error is returned.
Examples:
iex> fun = fn 0 -> {:error, :zero}; x -> {:ok, [1/x, 2/x, 3/x]} end
iex> Bunch.Enum.try_flat_map([1,5,-2,8], fun)
{:ok, [1.0, 2.0, 3.0, 0.2, 0.4, 0.6, -0.5, -1.0, -1.5, 0.125, 0.25, 0.375]}
iex> Bunch.Enum.try_flat_map([1,5,0,8], fun)
{:error, :zero}
@spec try_flat_map_reduce(Enum.t(), acc, fun :: (a, acc -> result)) :: result when a: any(), b: any(), acc: any(), result: Bunch.Type.stateful_try_t([b], acc)
Works like Enum.each/2
, but breaks on error.
Behaves like Enum.flat_map_reduce/3
as long as given fun
returns
{{:ok, value}, new_acc}
. If it happens to return {{:error, reason}, new_acc}
,
reduction is stopped and the error is returned.
Examples:
iex> fun = fn
...> x, acc when acc >= 0 -> {{:ok, [x+1, x+2, x+3]}, x + acc}
...> _, acc -> {{:error, :negative_prefix_sum}, acc}
...> end
iex> Bunch.Enum.try_flat_map_reduce([1,5,-2,8], 0, fun)
{{:ok, [2,3,4,6,7,8,-1,0,1,9,10,11]}, 12}
iex> Bunch.Enum.try_flat_map_reduce([1,5,-7,8], 0, fun)
{{:error, :negative_prefix_sum}, -1}
@spec try_map(Enum.t(), fun :: (a -> Bunch.Type.try_t(b))) :: Bunch.Type.try_t([b]) when a: any(), b: any()
Works like Enum.map/2
, but breaks on error.
Behaves like Enum.map/2
as long as given fun
returns {:ok, value}
.
If it happens to return {:error, reason}
, reduction is stopped and the
error is returned.
Examples:
iex> fun = fn 0 -> {:error, :zero}; x -> {:ok, 1/x} end
iex> Bunch.Enum.try_map([1,5,-2,8], fun)
{:ok, [1.0, 0.2, -0.5, 0.125]}
iex> Bunch.Enum.try_map([1,5,0,8], fun)
{:error, :zero}
@spec try_map_reduce( Enum.t(), acc, fun :: (a, acc -> Bunch.Type.stateful_try_t(b, acc)) ) :: Bunch.Type.stateful_try_t([b], acc) when a: any(), b: any(), acc: any()
Works like Enum.map_reduce/3
, but breaks on error.
Behaves like Enum.map_reduce/3
as long as given fun
returns
{{:ok, value}, new_acc}
. If it happens to return {{:error, reason}, new_acc}
,
reduction is stopped and the error is returned.
Examples:
iex> fun = fn
...> x, acc when acc >= 0 -> {{:ok, x+1}, x + acc}
...> _, acc -> {{:error, :negative_prefix_sum}, acc}
...> end
iex> Bunch.Enum.try_map_reduce([1,5,-2,8], 0, fun)
{{:ok, [2,6,-1,9]}, 12}
iex> Bunch.Enum.try_map_reduce([1,5,-7,8], 0, fun)
{{:error, :negative_prefix_sum}, -1}
@spec try_reduce(Enum.t(), acc, fun :: (a, acc -> result)) :: result when a: any(), acc: any(), result: Bunch.Type.stateful_try_t(acc)
Works like Enum.reduce/3
, but breaks on error.
Behaves like Enum.reduce/3
as long as given fun
returns {:ok, new_acc}
.
If it happens to return {{:error, reason}, new_acc}
, reduction is stopped and
the error is returned.
Examples:
iex> fun = fn
...> x, acc when acc >= 0 -> {:ok, x + acc}
...> _, acc -> {{:error, :negative_prefix_sum}, acc}
...> end
iex> Bunch.Enum.try_reduce([1,5,-2,8], 0, fun)
{:ok, 12}
iex> Bunch.Enum.try_reduce([1,5,-7,8], 0, fun)
{{:error, :negative_prefix_sum}, -1}
@spec try_reduce_while( Enum.t(), acc, reducer :: (a, acc -> Bunch.Type.stateful_try_t(:cont | :halt, acc)) ) :: Bunch.Type.stateful_try_t(acc) when a: any(), acc: any()
Works like Enum.reduce_while/3
, but breaks on error.
Behaves like Enum.reduce_while/3
as long as given fun
returns
{{:ok, :cont | :halt}, new_acc}
. If it happens to return
{{:error, reason}, new_acc}
, reduction is stopped and the error is returned.
Examples:
iex> fun = fn
...> 0, acc -> {{:ok, :halt}, acc}
...> x, acc when acc >= 0 -> {{:ok, :cont}, x + acc}
...> _, acc -> {{:error, :negative_prefix_sum}, acc}
...> end
iex> Bunch.Enum.try_reduce_while([1,5,-2,8], 0, fun)
{:ok, 12}
iex> Bunch.Enum.try_reduce_while([1,5,0,8], 0, fun)
{:ok, 6}
iex> Bunch.Enum.try_reduce_while([1,5,-7,8], 0, fun)
{{:error, :negative_prefix_sum}, -1}
Implementation of Enum.unzip/1
for more-than-two-element tuples.
Size of returned tuple is equal to size of the shortest tuple in tuples
.
Examples:
iex> Bunch.Enum.unzip([{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}])
{[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]}
iex> Bunch.Enum.unzip([{1,2,3}, {4,5}, {6,7,8,9}, {10,11,12}])
{[1, 4, 6, 10], [2, 5, 7, 11]}
Works the same way as Enum.zip/1
, but does not cut off remaining values.
Examples:
iex> Bunch.Enum.zip_longest([[1, 2] ,[3 ,4, 5]])
[[1, 3], [2, 4], [5]]
It also returns list of lists, as opposed to tuples.