Packages
moar
2.1.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/list.ex
defmodule Moar.List do
# @related [test](test/list_test.exs)
@doc """
Returns a list containing the first `count` items of `list`. If `list` is too small, it is repeated
until the requested size is acheived.
```elixir
iex> Moar.List.fill([1, 2, 3], 2)
[1, 2]
iex> Moar.List.fill([1, 2, 3], 7)
[1, 2, 3, 1, 2, 3, 1]
```
"""
@spec fill(list(), non_neg_integer()) :: list()
def fill(list, count),
do: list |> Stream.cycle() |> Enum.take(count)
@doc """
Converts a list to a keyword list, setting the value to `default_value`. The list can be a regular list, a keyword
list (which is a no-op), or a list that's a mix of terms and keywords (e.g., `[:a, :b, c: 3, d: 4]`). The default
value can be a term or a function that accepts a key and is expected to return a value.
```
iex> Moar.List.to_keyword([:a, :b, c: 3, d: 4])
[a: nil, b: nil, c: 3, d: 4]
iex> Moar.List.to_keyword([:a, :b, c: 3, d: 4], 1)
[a: 1, b: 1, c: 3, d: 4]
iex> Moar.List.to_keyword([:ant, :bird, cheetah: 7, dingo: 5], fn key -> key |> to_string() |> String.length() end)
[ant: 3, bird: 4, cheetah: 7, dingo: 5]
```
"""
@spec to_keyword(list(), (atom() -> term()) | term()) :: keyword()
def to_keyword(list, default_value \\ nil) do
if Keyword.keyword?(list) do
list
else
Keyword.new(list, fn
{key, value} ->
{key, value}
key ->
if is_function(default_value),
do: {key, default_value.(key)},
else: {key, default_value}
end)
end
end
@doc """
Converts a list to a comma-separated list that has "and" before the last item. The items in the list are converted
to strings via a mapper function, which defaults to `Kernel.to_string/1`.
```
iex> Moar.List.to_sentence([])
""
iex> Moar.List.to_sentence(["ant"])
"ant"
iex> Moar.List.to_sentence(["ant", :bat])
"ant and bat"
iex> Moar.List.to_sentence(["ant", :bat, "cat"])
"ant, bat, and cat"
iex> Moar.List.to_sentence(["ant", "bat", "cat"], &String.upcase/1)
"ANT, BAT, and CAT"
```
"""
@spec to_sentence([any()], (any() -> binary())) :: binary()
def to_sentence(list, mapper \\ &Kernel.to_string/1) do
case list |> List.wrap() |> Enum.reject(&Moar.Term.blank?/1) |> Enum.map(mapper) do
[] -> ""
[only] -> only
[first, second] -> [first, " and ", second]
list -> list |> Enum.intersperse(", ") |> List.insert_at(-2, "and ")
end
|> to_string()
end
@doc """
Returns the argument if it is not a list. If it is a list, returns the only item
in the list, or raises if the list is empty or has more than one item.
```
iex> Moar.List.unwrap!([5])
5
iex> Moar.List.unwrap!(5)
5
iex> Moar.List.unwrap!([])
** (FunctionClauseError) no function clause matching in Moar.List.unwrap!/1
iex> Moar.List.unwrap!([5, 9])
** (FunctionClauseError) no function clause matching in Moar.List.unwrap!/1
```
"""
@spec unwrap!(any() | [any()]) :: any()
def unwrap!([term]), do: term
def unwrap!(term) when not is_list(term), do: term
end