Packages
moar
1.26.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/enum.ex
defmodule Moar.Enum do
# @related [test](/test/enum_test.exs)
@moduledoc "Enum-related functions."
@doc "Like `Enum.at/3` but raises if `index` is out of bounds."
@spec at!(Enum.t(), integer() | [integer()], any()) :: any()
def at!(enum, index, default \\ nil) when is_integer(index) do
if length(enum) < index + 1,
do: raise("Out of range: index #{index} of enum with length #{length(enum)}: #{inspect(enum)}"),
else: Enum.at(enum, index, default)
end
@doc "Removes nil elements from `enum`."
@spec compact(Enum.t()) :: Enum.t()
def compact(enum),
do: enum |> Enum.reject(&is_nil(&1))
@doc "Returns the first item of `enum`, or raises if it is empty."
@spec first!(Enum.t()) :: any()
def first!(enum),
do: Enum.at(enum, 0) || raise("Expected enumerable to have at least one item")
@doc """
Returns true if the value is a map or a keyword list.
This cannot be used as a guard because it uses `Keyword.keyword?` under the hood. Also, because of that,
it might scan an entire list to see if it's a keyword list, so it might be expensive.
"""
@spec is_map_or_keyword(any()) :: boolean()
def is_map_or_keyword(value),
do: is_map(value) || (is_list(value) && Keyword.keyword?(value))
@doc "Sorts `enum` case-insensitively. Uses `Enum.sort_by/3` under the hood."
@spec isort(Enum.t()) :: Enum.t()
def isort(enum),
do: enum |> isort_by(&to_string/1)
@doc "Sorts `enum` case-insensitively by `mapper` function. Uses `Enum.sort_by/3` under the hood."
@spec isort_by(Enum.t(), (any() -> any())) :: Enum.t()
def isort_by(enum, mapper),
do: enum |> Enum.sort_by(&(mapper.(&1) |> String.downcase()))
@doc """
Returns a list of elements at the given indices. If `:all` is given instead of a list of indices, the entire
enum is returned.
```elixir
iex> Moar.Enum.take_at(["A", "B", "C"], [0, 2])
["A", "C"]
iex> Moar.Enum.take_at(["A", "B", "C"], :all)
["A", "B", "C"]
```
"""
@spec take_at(Enum.t(), integer() | [integer()] | :all) :: any()
def take_at(enum, :all), do: enum
def take_at(enum, list) when is_list(list), do: Enum.map(list, &Enum.at(enum, &1))
@doc """
Returns `:tid` fields from `enumerable`.
This unusual function exists because the authors of Moar use tids (test IDs) extensively in tests.
"""
@spec tids(Enum.t()) :: list()
def tids(enumerable),
do: enumerable |> Enum.map(& &1.tid)
end