ex_aequo

CICoverage StatusHex.pmHex.pmHex.pm

ExAequo Elixir Tools

Installation:

  { :ex_aequo, ">= 0.2.2" }

Meaning of the name. All nice latin expressions starting with Ex are consumed at an alarming rate, so, all things being equal, I choose this one.

ExAequo.Enum offers some extension functions for Elixir's Enum module

Grouped Accumulation

Groupes accumulated values of an Enum according to a function that indicates if two consequent items are of the same kind and if so how to accumulate their two values.

The grouped_reduce function returns the groupes in reverse order, as, during traversal of lists quite often reversing the result of the classical "take first and push a function of it to the result" pattern cancels out.

An optional, reverse: true keyword option can be provided to reverse the final result for convenience.

  iex(0)> add_same = fn {x, a}, {y, b} ->
  ...(0)>               cond do
  ...(0)>                 x == y -> {:cont, {x, a + b}}
  ...(0)>                 true   -> {:stop, nil} end end
  ...(0)> E.grouped_reduce(
  ...(0)>   [{:a, 1}, {:a, 2}, {:b, 3}, {:b, 4}], add_same)
  [{:b, 7}, {:a, 3}]

The grouped_inject function behaves almost identically to grouped_reduce, however an initial value is provided.

  iex(1)> sub_same = fn {x, a}, {y, b} -> 
  ...(1)>               cond do
  ...(1)>                 x == y -> {:cont, {x, a - b}}
  ...(1)>                 true   -> {:stop, nil}
  ...(1)>               end
  ...(1)>            end
  ...(1)> E.grouped_inject(
  ...(1)> [{:a, 1}, {:b, 2}, {:b, 2}, {:c, 2}, {:c, 1}, {:c, 1}],
  ...(1)>  {:a, 43}, sub_same, reverse: true)
  [a: 42, b: 0, c: 0]

Tools to facilitate dispatching on keyword parameters, used in contexts like the following

  @defaults [a: 1, b: false] # Keyword or Map
  def some_fun(..., options \ []) # options again can be a Keyword or Map
    {a, b} = tuple_from_params(@defaults, options, [:a, :b])

Merging defaults and actual parameters

Its most useful feature is that you will get a map whatever the mixtures of maps and keywords the input was

    iex(0)> merge_params([])
    %{}

    iex(1)> merge_params([a: 1], %{b: 2})
    %{a: 1, b: 2}

    iex(2)> merge_params(%{a: 1}, [a: 2, b: 2])
    %{a: 2, b: 2}

Strict merging

Not implemented yet

Extracting params from the merged defaults and actuals

iex(3)> defaults = [foo: false, depth: 3]
...(3)> tuple_from_params(defaults, %{foo: true}, [:foo, :depth])
{true, 3}

As defaults are required a missing parameter will raise an Error

iex(4)> try do
...(4)>   tuple_from_params([], [foo: 1], [:bar])
...(4)> rescue
...(4)>   KeyError -> :caught
...(4)> end
:caught

Alternatively on can extract a map

iex(5)> map_from_params([], [hello: "world"], [:hello])
%{hello: "world"}

This is the 2 param form which is identical to an empty default map

iex(6)> map_from_params(%{a: 1, b: 2}, [:a])
%{a: 1}

This is the 2 param form which is identical to an empty default map

iex(7)> tuple_from_params(%{a: 1, b: 2}, [:b, :a])
{2, 1}
    iex(0)> base_name_without_ext("a/b/c.txt")
    "c"

    iex(1)> base_name_without_ext("a/b/c.txt.eex")
    "c.txt"

    iex(2)> base_name_without_ext("a/b/c")
    "c"
    iex(3)> full_name_without_ext("a/b/c.txt")
    "a/b/c"

    iex(4)> full_name_without_ext("a/b/c.txt.eex")
    "a/b/c.txt"

    iex(5)> full_name_without_ext("a/b/c")
    "a/b/c"

    iex(6)> full_name_without_ext("/c")
    "/c"

SPDX-License-Identifier: Apache-2.0