Map Sorter v0.1.9 MapSorter.Support View Source

Generates a sort function from a list of sort specs.

Link to this section Summary

Functions

Adapts a string to invoke the sortable/1 function

Takes a list of sort specs (ascending/descending keys)

Takes a list of sort specs (ascending/descending keys)

Converts a value to a sortable format, if needed

Link to this section Types

Link to this type sort_dir() View Source
sort_dir() :: :asc | :desc
Link to this type sort_fun() View Source
sort_fun() :: (map(), map() -> boolean())
Link to this type sort_spec() View Source
sort_spec() :: Map.key() | {sort_dir(), Map.key()}

Link to this section Functions

Link to this function adapted_string(string) View Source
adapted_string(String.t()) :: String.t()

Adapts a string to invoke the sortable/1 function.

Examples

iex> alias MapSorter.Support
iex> Support.adapted_string(
...>   """
...>   &1[:bmi]
...>   &1[:sex]
...>   """
...> )
"""
MapSorter.Support.sortable(&1[:bmi])
MapSorter.Support.sortable(&1[:sex])
"""
Link to this function eval_sort_fun(sort_specs) View Source
eval_sort_fun([sort_spec()]) :: sort_fun()

Takes a list of sort specs (ascending/descending keys).

Returns a sort function based on the given sort specs which compares two maps¹ and returns true if the first map precedes the second one.

¹Or keywords or structures implementing the Access behaviour.

Examples

iex> alias MapSorter.Support
iex> Logger.configure(level: :info) # :debug => debug messages
iex> sort_fun = Support.eval_sort_fun([:bmi, desc: :likes])
iex> Logger.configure(level: :info) # :info => no debug messages
iex> here_string =
...>   """
...>   & cond do
...>   &1[:bmi] < &2[:bmi] -> true
...>   &1[:bmi] > &2[:bmi] -> false
...>   &1[:likes] > &2[:likes] -> true
...>   &1[:likes] < &2[:likes] -> false
...>   true -> true
...>   end
...>   """
iex> {here_fun, []} =
...>   here_string
...>   |> Support.adapted_string()
...>   |> Code.eval_string()
iex> sort_fun == here_fun and
...> is_function(sort_fun, 2)
true
Link to this function sort_fun_ast(sort_specs) View Source
sort_fun_ast({any(), any(), any()}) :: {{:., any(), any()}, any(), any()}
sort_fun_ast([sort_spec()]) :: {:&, any(), any()}

Takes a list of sort specs (ascending/descending keys).

Returns the AST of a sort function based on the given sort specs allowing to sort a list of maps¹.

The sort function will compare two maps¹ and return true if the first map precedes the second one.

—Or—

Takes the AST of an expression that will evaluate at runtime to a list of sort specs (ascending/descending keys).

Returns the AST of a function call to evaluate the sort function at runtime.

¹Or keywords or structures implementing the Access behaviour.

Examples

iex> alias MapSorter.Support
iex> Logger.configure(level: :info) # :debug => debug messages
iex> sort_fun_ast = Support.sort_fun_ast([:height, desc: :likes])
iex> Logger.configure(level: :info) # :info => no debug messages
iex> here_string =
...>   """
...>   & cond do
...>   &1[:height] < &2[:height] -> true
...>   &1[:height] > &2[:height] -> false
...>   &1[:likes] > &2[:likes] -> true
...>   &1[:likes] < &2[:likes] -> false
...>   true -> true
...>   end
...>   """
iex> {:ok, here_ast} =
...>   here_string
...>   |> Support.adapted_string()
...>   |> Code.string_to_quoted()
iex> sort_fun_ast == here_ast and
...> match?({:&, _meta, _args}, sort_fun_ast)
true

iex> alias MapSorter.Support
iex> Logger.configure(level: :info) # :debug => debug messages
iex> {sort_fun, []} =
iex>   [:weight, desc: :likes]
...>   |> Support.sort_fun_ast()
...>   |> Code.eval_quoted()
iex> Logger.configure(level: :info) # :info => no debug messages
iex> here_string =
...>   """
...>   & cond do
...>   &1[:weight] < &2[:weight] -> true
...>   &1[:weight] > &2[:weight] -> false
...>   &1[:likes] > &2[:likes] -> true
...>   &1[:likes] < &2[:likes] -> false
...>   true -> true
...>   end
...>   """
iex> {here_fun, []} =
...>   here_string
...>   |> Support.adapted_string()
...>   |> Code.eval_string()
iex> sort_fun == here_fun and
...> is_function(sort_fun, 2)
true

iex> alias MapSorter.Support
iex> sort_specs_ast = quote do: Tuple.to_list({:dept, {:desc, :dob}})
iex> Logger.configure(level: :info) # :debug => debug messages
iex> {sort_fun, []} =
...>   sort_specs_ast
...>   |> Support.sort_fun_ast()
...>   |> Code.eval_quoted()
iex> eval_sort_fun = Support.eval_sort_fun([:dept, desc: :dob])
iex> Logger.configure(level: :info) # :info => no debug messages
iex> Tuple.to_list({:dept, {:desc, :dob}}) == [:dept, desc: :dob] and
...> sort_fun == eval_sort_fun and
...> is_function(sort_fun, 2)
true
Link to this function sortable(value) View Source
sortable(any()) :: String.t() | any()

Converts a value to a sortable format, if needed.

Examples

iex> alias MapSorter.Support
iex> Support.sortable(~D[2017-11-01])
"2017-11-01"

iex> alias MapSorter.Support
iex> Support.sortable(~T[15:41:33])
"15:41:33"

iex> alias MapSorter.Support
iex> Support.sortable(3.1416)
3.1416

iex> alias MapSorter.Support
iex> Support.sortable(%{z: 26, y: 25, a: 1})
%{z: 26, y: 25, a: 1}