MapSorter.Compare (Map Sorter v0.2.72)

Copy Markdown View Source

A compare function and a heredoc to become a compare function.

Summary

Types

Compare function

Functions

Generates an Enum.sort/2 compare function from a list of sort specs.

Generates a cond/1 expression as a heredoc to become a compare function.

Types

comp_fun()

@type comp_fun() :: (Access.container(), Access.container() -> boolean())

Compare function

Functions

fun(sort_specs)

@spec fun(MapSorter.SortSpecs.t()) :: comp_fun()

Generates an Enum.sort/2 compare function from a list of sort specs.

Examples

# To run multiple doctests sequentially, remove empty lines between them.
iex> alias MapSorter.{Compare, Log}
iex> Log.debug(:doctest_id, {:compare_id_1, __ENV__})
iex> sort_specs = [:dob, desc: :likes]
iex> fun = Compare.fun(sort_specs)
iex> map1 = %{name: "John", dob: "2000-01-01", likes: "ski"}
iex> map2 = %{name: "Jane", dob: "2000-01-01", likes: "hike"}
iex> is_function(fun, 2) and fun.(map1, map2)
true
# Compare function always true => no reordering...
iex> alias MapSorter.{Compare, Log}
iex> Log.debug(:doctest_id, {:compare_id_2, __ENV__})
iex> sort_specs = {:dob, desc: :likes}
iex> fun = Compare.fun(sort_specs)
iex> is_function(fun, 2) and fun.(1, 2) and fun.(2, 1)
true
iex> alias MapSorter.{Compare, Log}
iex> Log.debug(:doctest_id, {:compare_id_3, __ENV__})
iex> sort_specs = fn -> [:dob, desc: :likes] end
iex> fun = Compare.fun(sort_specs.())
iex> map1 = %{name: "John", dob: "2000-01-01", likes: "ski"}
iex> map2 = %{name: "Jane", dob: "2000-01-01", likes: "hike"}
iex> is_function(fun, 2) and fun.(map1, map2)
true
iex> alias MapSorter.{Compare, Log}
iex> Log.debug(:doctest_id, {:compare_id_4, __ENV__})
iex> sort_specs = Tuple.to_list({:dob, {:desc, :likes}})
iex> fun = Compare.fun(sort_specs)
iex> map1 = %{name: "John", dob: "2000-01-01", likes: "ski"}
iex> map2 = %{name: "Jane", dob: "2000-01-01", likes: "hike"}
iex> is_function(fun, 2) and fun.(map1, map2)
true

heredoc(sort_specs)

@spec heredoc(MapSorter.SortSpecs.t()) :: String.t()

Generates a cond/1 expression as a heredoc to become a compare function.

The heredoc may be converted into its quoted form at compile time or else have its contents evaluated at runtime.

This function cannot be named cond as it is among the Kernel.SpecialForms.

Examples

iex> alias MapSorter.Compare
iex> Compare.heredoc([])
"""
& cond do
true -> true or &1 > &2
end
"""

iex> alias MapSorter.Compare
iex> sort_specs = [:name, {:desc, :dob}]
iex> Compare.heredoc(sort_specs)
"""
& cond do
&1[:name] < &2[:name] -> true
&1[:name] > &2[:name] -> false
&1[:dob] > &2[:dob] -> true
&1[:dob] < &2[:dob] -> false
true -> true or &1 > &2
end
"""

iex> alias MapSorter.Compare
iex> sort_specs = [:name, {:desc, {:dob, Date}}]
iex> Compare.heredoc(sort_specs)
"""
& cond do
&1[:name] < &2[:name] -> true
&1[:name] > &2[:name] -> false
&1[:dob] != nil and Date.compare(&1[:dob], &2[:dob]) == :gt -> true
&1[:dob] != nil and Date.compare(&1[:dob], &2[:dob]) == :lt -> false
true -> true or &1 > &2
end
"""

iex> alias MapSorter.Compare
iex> sort_specs = [:name, {:desc, {:account, Path}}]
iex> Compare.heredoc(sort_specs)
"""
& cond do
&1[:name] < &2[:name] -> true
&1[:name] > &2[:name] -> false
&1[{:account, Path}] > &2[{:account, Path}] -> true
&1[{:account, Path}] < &2[{:account, Path}] -> false
true -> true or &1 > &2
end
"""