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

Link to this function

chunk_by_prev(enum, chunker, collector \\ & &1)

View Source
@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]
Link to this function

duplicates(enum, min_occurences \\ 2)

View Source
@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}
Link to this function

try_flat_map_reduce(enum, acc, f)

View Source
@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}
Link to this function

try_map_reduce(enum, acc, f)

View Source
@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}
Link to this function

try_reduce(enum, acc, f)

View Source
@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}
Link to this function

try_reduce_while(enum, acc, f)

View Source
@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}
@spec unzip(tuples :: [tuple()]) :: tuple()

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]}
@spec zip_longest(list()) :: [list()]

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.