Bunch v0.1.0 Bunch.Enum View Source

A bunch of helper functions for manipulating enums.

Link to this section Summary

Functions

Splits enumerable into chunks, and passes each chunk through collector

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
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]
Link to this function repeat(fun, i) View Source
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)
[]
Link to this function repeated(v, i) View Source
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)
[]
Link to this function try_each(enum, f) View Source
try_each(Enum.t(), fun :: (a -> result)) :: result
when a: any(), result: :ok | {:error, any()}

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}
Link to this function try_flat_map(enum, f) View Source
try_flat_map(Enum.t(), fun :: (a -> result)) :: result
when a: any(), b: any(), result: {:ok, [b]} | {:error, any()}

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}
Link to this function try_flat_map_reduce(enum, acc, f) View Source
try_flat_map_reduce(Enum.t(), acc, fun :: (a, acc -> result)) :: result
when a: any(),
     b: any(),
     acc: any(),
     result: {{:ok, [b]} | {:error, any()}, 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}
Link to this function try_map(enum, f) View Source
try_map(Enum.t(), fun :: (a -> {:ok, b} | error)) :: {:ok, [b]} | error
when a: any(), b: any(), error: {:error, 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}
Link to this function try_map_reduce(enum, acc, f) View Source
try_map_reduce(Enum.t(), acc, fun :: (a, acc -> {{:ok, b}, acc} | error)) ::
  {{:ok, [b]}, acc} | error
when a: any(), b: any(), acc: any(), error: {:error, 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 returend.

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
try_reduce(Enum.t(), acc, fun :: (a, acc -> result)) :: result
when a: any(), acc: any(), result: {:ok, acc} | {{:error, any()}, 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}
Link to this function try_reduce_while(enum, acc, f) View Source
try_reduce_while(
  Enum.t(),
  acc,
  reducer :: (a, acc -> {{:ok, :cont | :halt} | error, acc})
) :: {:ok, acc} | {error, acc}
when a: any(), acc: any(), error: {:error, 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 returend.

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}
Link to this function unzip(list) View Source
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:

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]}
Link to this function zip_longest(lists) View Source
zip_longest(list()) :: [list()]

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.