View Source Bunch.Enum (Bunch v1.3.1)
A bunch of helper functions for manipulating enums.
Link to this section 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.
Link to this section 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
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
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
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
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
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
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
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
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
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
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
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.