Packages

Things I didn't want to have to write again.

Current section

Files

Jump to
ex_utils_caddr lib caddr.ex
Raw

lib/caddr.ex

defmodule Caddr do
@moduledoc """
Documentation for Elixir Utils by Caddr.
"""
@doc """
Uniq -c
## Examples
iex> Caddr.uniqc([1,2,3,1,2,3,1,2,4])
%{1 => 3, 2 => 3, 3 => 2, 4 => 1}
"""
def uniqc(e) do
Enum.map(e, &({&1}))
|> reduce_groups({0}, [{&Enum.count/1, 0}])
|> Map.to_list
|> Enum.map(fn {{x}, {y}} -> {x, y} end)
|> Map.new
end
@doc """
Reduce by groups. Similar to SELECT x, y, SUM(z), SUM(w) FROM stuff GROUP BY (x,y);
This will always return tuples even if single items in a list are passed in.
## Examples
iex(1)> Caddr.reduce_groups([1, 2, 3, 1, 2, 3], {0}, [{&Enum.count/1, 0}])
%{{1} => {2}, {2} => {2}, {3} => {2}}
iex> Caddr.reduce_groups([{1,2,3,5}, {1,2,1,5}, {1,1,1,5}], {0, 1}, [{&Enum.sum/1, 2}, {&Enum.sum/1, 3}])
%{{1, 2} => {4, 10}, {1, 1} => {1, 5}}
"""
def reduce_groups(e, gb, aggs) do
e
|> Enum.map(&tuplize/1)
|> Enum.group_by(&(select_from_tuple(&1, gb)))
|> Map.to_list
|> Enum.map(fn {g, n} ->
{g, aggregate_tuple(n, aggs)}
end)
|> Map.new
end
@doc """
Aggregate tuple
## Examples
iex> Caddr.aggregate_tuple([{1,2,3}, {3,4,5}], [{&Enum.sum/1, 2}, {&Enum.count/1, 0}])
{8, 2}
"""
def aggregate_tuple(_, []), do: {}
def aggregate_tuple(e, [{agg, aggn}| r]) do
Tuple.insert_at(aggregate_tuple(e, r), 0,
e |> Enum.map(&(elem(&1, aggn))) |> agg.()
)
end
@doc """
## Examples
iex> Caddr.select_from_tuple({1,2,3,4,5}, {3,2})
{4, 3}
"""
def select_from_tuple(t, el) do
Tuple.to_list(el)
|> Enum.reduce({}, fn y,x -> Tuple.append(x, elem(tuplize(t), y)) end)
end
defp tuplize(t) when is_tuple(t), do: t
defp tuplize(t), do: {t}
end