Enum.min_by

You're seeing just the function min_by, go back to Enum module for more information.
Link to this function

min_by(enumerable, fun, sorter \\ &<=/2, empty_fallback \\ fn -> raise(Enum.EmptyError) end)

View Source

Specs

min_by(
  t(),
  (element() -> any()),
  (element(), element() -> boolean()) | module(),
  (() -> empty_result)
) :: element() | empty_result
when empty_result: any()

Returns the minimal element in the enumerable as calculated by the given fun.

By default, the comparison is done with the <= sorter function. If multiple elements are considered minimal, the first one that was found is returned. If you want the last element considered minimal to be returned, the sorter function should not return true for equal elements.

Calls the provided empty_fallback function and returns its value if enumerable is empty. The default empty_fallback raises Enum.EmptyError.

Examples

iex> Enum.min_by(["a", "aa", "aaa"], fn x -> String.length(x) end)
"a"

iex> Enum.min_by(["a", "aa", "aaa", "b", "bbb"], &String.length/1)
"a"

The fact this function uses Erlang's term ordering means that the comparison is structural and not semantic. Therefore, if you want to compare structs, most structs provide a "compare" function, such as Date.compare/2, which receives two structs and returns :lt (less-than), :eq (equal to), and :gt (greater-than). If you pass a module as the sorting function, Elixir will automatically use the compare/2 function of said module:

iex> users = [
...>   %{name: "Ellis", birthday: ~D[1943-05-11]},
...>   %{name: "Lovelace", birthday: ~D[1815-12-10]},
...>   %{name: "Turing", birthday: ~D[1912-06-23]}
...> ]
iex> Enum.min_by(users, &(&1.birthday), Date)
%{name: "Lovelace", birthday: ~D[1815-12-10]}

Finally, if you don't want to raise on empty enumerables, you can pass the empty fallback:

iex> Enum.min_by([], &String.length/1, fn -> nil end)
nil