Multi-key Elixir record sort with nil-last order
Elixir
defmodule RecordSort do
def by_keys(records, keys) do
Enum.sort(records, fn a, b ->
compare_keys(keys, a, b) != :gt
end)
end
defp compare_keys([], _a, _b), do: :eq
defp compare_keys([key | rest], a, b) do
case compare_nullable(Map.get(a, key), Map.get(b, key)) do
:eq -> compare_keys(rest, a, b)
order -> order
end
end
defp compare_nullable(nil, nil), do: :eq
defp compare_nullable(nil, _), do: :gt
defp compare_nullable(_, nil), do: :lt
defp compare_nullable(a, b), do: if(a < b, do: :lt, else: if(a > b, do: :gt, else: :eq))
end