Packages
map_sorter
0.1.1
0.2.70
0.2.69
0.2.68
0.2.67
0.2.66
0.2.65
0.2.64
0.2.63
0.2.62
0.2.61
0.2.60
0.2.59
0.2.58
0.2.57
0.2.56
0.2.55
0.2.54
0.2.53
0.2.52
0.2.51
0.2.50
0.2.49
0.2.48
0.2.47
0.2.46
0.2.45
0.2.44
0.2.42
0.2.41
0.2.40
0.2.39
0.2.38
0.2.37
0.2.36
0.2.35
0.2.34
0.2.33
0.2.32
0.2.31
0.2.30
0.2.29
0.2.28
0.2.27
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.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
Sorts a list of maps per a list of sort specs.
Current section
Files
Jump to
Current section
Files
lib/map_sorter.ex
defmodule MapSorter do
@moduledoc """
Generates the AST to sort maps per sort specs (ascending/descending keys).
"""
require Logger
@doc """
Takes a list of `maps` and either a list of `sort specs` or an AST
that will evaluate to a list of `sort specs` at runtime.
Returns the AST to sort the `maps` per the `sort specs`.
`sort specs` can be implicit, explicit or mixed:
- [:dob, :name] is implicit ⇒ [asc: :dob, asc: :name]
- [:dob, desc: :name] is mixed ⇒ [asc: :dob, desc: :name]
- [asc: :dob, desc: :name] is explicit
## Examples
iex> require MapSorter
iex> people = [
...> %{name: "Mike", likes: "ski, arts", dob: "1992-04-15"},
...> %{name: "Mary", likes: "travels" , dob: "1992-04-15"},
...> %{name: "Ann" , likes: "reading" , dob: "1992-04-15"},
...> %{name: "Ray" , likes: "cycling" , dob: "1977-08-28"},
...> %{name: "Bill", likes: "karate" , dob: "1977-08-28"},
...> %{name: "Joe" , likes: "boxing" , dob: "1977-08-28"},
...> %{name: "Jill", likes: "cooking" , dob: "1976-09-28"}
...> ]
iex> MapSorter.log_level(:info) # :debug ⇒ debug messages
iex> fun = & &1
iex> sorted = %{
...> explicit: MapSorter.sort(people, asc: :dob, desc: :likes),
...> implicit: MapSorter.sort(people, [:dob, desc: :likes]),
...> function: MapSorter.sort(people, fun.([:dob, desc: :likes]))
...> }
iex> MapSorter.log_level(:info) # :info ⇒ no debug messages
iex> sorted.explicit == sorted.implicit and
...> sorted.explicit == sorted.function and
...> sorted.explicit
[
%{name: "Jill", likes: "cooking" , dob: "1976-09-28"},
%{name: "Bill", likes: "karate" , dob: "1977-08-28"},
%{name: "Ray" , likes: "cycling" , dob: "1977-08-28"},
%{name: "Joe" , likes: "boxing" , dob: "1977-08-28"},
%{name: "Mary", likes: "travels" , dob: "1992-04-15"},
%{name: "Mike", likes: "ski, arts", dob: "1992-04-15"},
%{name: "Ann" , likes: "reading" , dob: "1992-04-15"}
]
"""
defmacro sort(maps, sort_specs) do
Logger.debug("sort specs: #{inspect sort_specs}...")
sort_fun_ast =
case sort_specs do
specs when is_list(specs) -> specs
specs -> Macro.expand(specs, __CALLER__) # in case module attribute
end
|> MapSorter.Support.sort_fun_ast()
quote do: Enum.sort(unquote(maps), unquote(sort_fun_ast))
end
@doc """
Allows to change the log `level` at compile time.
"""
defmacro log_level(level), do: Logger.configure(level: level)
end