Packages
moar
1.57.0
5.0.0
4.3.0
4.2.0
4.1.0
4.0.0
3.2.0
3.1.0
3.0.0
2.7.0
2.6.0
2.5.0
2.4.2
2.4.1
2.4.0
2.3.0
2.2.0
2.1.0
2.0.1
2.0.0
1.64.0
1.63.1
1.63.0
1.62.0
1.61.2
1.61.1
1.61.0
1.60.0
1.59.2
1.59.1
1.59.0
1.58.0
1.57.0
1.56.2
1.56.1
1.56.0
1.55.0
1.54.0
1.53.0
1.52.1
1.52.0
1.51.0
1.50.0
1.49.0
1.48.0
1.47.0
1.46.0
1.45.1
1.45.0
1.44.0
1.43.0
1.42.0
1.41.0
1.40.0
1.39.0
1.38.0
1.37.0
1.36.0
1.35.0
1.34.0
1.33.0
1.32.0
1.31.0
1.30.0
1.29.0
1.28.0
1.27.0
1.26.0
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.0
1.19.3
1.19.2
1.19.1
1.19.0
1.18.1
1.18.0
1.17.0
1.16.0
1.15.0
1.14.0
1.13.1
1.13.0
1.12.0
1.11.0
1.10.0
1.9.0
1.8.0
1.7.0
1.6.0
1.5.0
1.4.0
1.3.0
1.2.0
1.1.0
1.0.0
0.1.0
A dependency-free utility library containing 100+ useful functions.
Current section
Files
Jump to
Current section
Files
lib/tuple.ex
defmodule Moar.Tuple do
# @related [test](/test/tuple_test.exs)
@moduledoc "Tuple-related functions."
@doc """
Converts a list of tuples to a single tuple whose first element is the first element of each tuple in
the list (which must all be the same), and whose second element is a list containing the second elements
of each tuple in the list.
Raises if the list contains tuples whose first elements are not all the same.
```elixir
iex> Moar.Tuple.from_list!([{:ok, :a}, {:ok, :b}])
{:ok, [:a, :b]}
iex> Moar.Tuple.from_list!([{:a, 1}, {:a, 2}, {:a, 3}])
{:a, [1, 2, 3]}
iex> Moar.Tuple.from_list!([{:a, 1}, {:b, 2}, {:a, 3}])
** (RuntimeError) Expected all items in the list to have have the same first element, but got: [:a, :b]
```
"""
@spec from_list!([any()]) :: {any(), [any()]}
def from_list!(list) do
{keys, values} = Enum.unzip(list)
case Enum.uniq(keys) do
[key] -> {key, values}
keys -> raise "Expected all items in the list to have have the same first element, but got: #{inspect(keys)}"
end
end
@doc """
Reduces a list of tuples to map where values are consolidated by the first element of each input tuple.
```elixir
iex> Moar.Tuple.reduce([{:ok, 1}, {:ok, 2}])
%{ok: [1, 2]}
iex> Moar.Tuple.reduce([{:ok, 1}, {:ok, 2}, {:error, 3}, {:ok, 4}])
%{ok: [1, 2, 4], error: [3]}
```
"""
@spec reduce([any()]) :: map()
def reduce(list) do
Enum.reduce(list, %{}, fn {k, v}, acc ->
Map.update(acc, k, [v], fn list -> [v | list] end)
end)
|> Map.new(fn {k, v} -> {k, Enum.reverse(v)} end)
end
end