Filters (filters v0.1.1)

Models a list of filters to apply to a collection (list) of data items

Link to this section Summary

Functions

Add or update an existing filter in the list. Two filters cannot have the same :filter_type and :key.

Filter the provided data with a list of filters

Serialize a list of filters into URL query parameters

Return a filter matching by :filter_type and :key

Create a new set of filters

Return a tuple with the found filter and the remaining ones

Deserialize URL query parameters into a list of filters

Link to this section Types

Link to this type

filters_data()

@type filters_data() :: [%{required(Filters.Filter.key()) => String.t()}]
@type logic() :: :or | :and
@type t() :: %Filters{
  filters: [%Filters.Filter{filter_type: term(), key: term(), value: term()}],
  logic: logic()
}

Link to this section Functions

Link to this function

add_update(fs, f)

Add or update an existing filter in the list. Two filters cannot have the same :filter_type and :key.

Link to this function

filter(data, filters)

@spec filter(filters_data(), t()) :: filters_data()

Filter the provided data with a list of filters

examples

Examples

text-filters

Text filters

iex> filters = Filters.new()
...> |> Filters.add_update(Filters.Filter.new(:text, :is, "liv"))
iex> Filters.filter([
...>  %{type: "human",   is: "Philip J. Fry"},
...>  %{type: "robot",   is: "Bender Rodriguez"},
...>  %{type: "human",   is: "Turanga Leila"},
...>  %{type: "robot",   is: "R. Daneel Oliva"},
...>  %{type: "drink",   is: "Martini with an olive"},
...>  %{type: "actions", are: "eat, live, think"}
...>  ], filters)
[
  %{type: "drink", is: "Martini with an olive"},
  %{type: "robot", is: "R. Daneel Oliva"}
]

enum-filters

Enum filters

iex> filters = Filters.new()
...> |> Filters.add_update(Filters.Filter.new(:enum, :type, "human"))
iex> Filters.filter([
...>  %{type: "human", is: "Philip J. Fry"},
...>  %{type: "robot", is: "Bender Rodriguez"},
...>  %{type: "human", is: "Turanga Leila"},
...>  %{type: "humanoid", is: "R. Daneel Oliva"}
...>  ], filters)
[
  %{type: "human", is: "Turanga Leila"},
  %{type: "human", is: "Philip J. Fry"}
]

date-filters

Date filters

iex> filters = Filters.new()
...> |> Filters.add_update(Filters.Filter.new(:date_from, :birthday, "2042-11-12"))
...> |> Filters.add_update(Filters.Filter.new(:date_to,   :birthday, "2042-12-12"))
iex> Filters.filter([
...>  %{birthday: "2042-12-11", of: "Bender Rodriguez"},
...>  %{birthday: "2042-11-11", of: "Philip J. Fry"},
...>  %{birthday: "2042-11-12", of: "Turanga Leila"},
...>  %{birthday: "2042-11-13", of: "Hubert Farnsworth"},
...>  %{birthday: "2042-12-12", of: "Amy Wong"},
...>  %{birthday: "2042-12-13", of: "Doctor Zoidberg"},
...>  %{birthday: "2042-12-12", of: "Hermes Conrad"}
...>  ], filters)
[
  %{birthday: "2042-12-12", of: "Hermes Conrad"},
  %{birthday: "2042-12-12", of: "Amy Wong"},
  %{birthday: "2042-11-13", of: "Hubert Farnsworth"},
  %{birthday: "2042-11-12", of: "Turanga Leila"},
  %{birthday: "2042-12-11", of: "Bender Rodriguez"}
]

multiple-filters-and-logic

Multiple filters (and logic)

iex> filters = Filters.new()
...> |> Filters.add_update(Filters.Filter.new(:enum, :type, "human"))
...> |> Filters.add_update(Filters.Filter.new(:text, :is, "Leila"))
iex> Filters.filter([
...>  %{hello: "world", type: "human", is: "Philip J. Fry"},
...>  %{hello: "world", type: "robot", is: "Bender Rodriguez"},
...>  %{hell: "world",  type: "human", is: "Turanga Leila"},
...>  %{hello: "word",  type: "humanoid", is: "R. Daneel Oliva"}
...>  ], filters)
[
  %{hell: "world",  type: "human", is: "Turanga Leila"}
]

multiple-filters-or-logic

Multiple filters (or logic)

iex> filters = Filters.new(:or)
...> |> Filters.add_update(Filters.Filter.new(:enum, :type, "human"))
...> |> Filters.add_update(Filters.Filter.new(:text, :is, "Bender"))
iex> Filters.filter([
...>  %{hello: "world", type: "human", is: "Philip J. Fry"},
...>  %{hello: "world", type: "robot", is: "Bender Rodriguez"},
...>  %{hell: "world",  type: "human", is: "Turanga Leila"},
...>  %{hello: "word",  type: "humanoid", is: "R. Daneel Oliva"}
...>  ], filters)
[
  %{hell: "world",  type: "human", is: "Turanga Leila"},
  %{hello: "world", type: "robot", is: "Bender Rodriguez"},
  %{hello: "world", type: "human", is: "Philip J. Fry"}
]
Link to this function

filters_to_query(filters, opts \\ [])

Serialize a list of filters into URL query parameters

example

Example

iex> %Filters{
...>  filters: [
...>    %Filters.Filter{filter_type: :text, key: :genre, value: "industrial metal"},
...>    %Filters.Filter{filter_type: :text, key: :artist, value: "Dance With"}
...>  ],
...>  logic: :and
...> } |> Filters.filters_to_query() |> URI.decode()
"logic=and&genre=text|industrial metal&artist=text|Dance With"

Return a filter matching by :filter_type and :key

Link to this function

new(logic \\ :and, filters \\ [])

Create a new set of filters

Link to this function

pop(fs, filter)

@spec pop(t(), Filters.Filter.t()) ::
  {[Filters.Filter.t()] | [], [Filters.Filter.t()]}

Return a tuple with the found filter and the remaining ones

Useful to drop a filter or to update it

Link to this function

query_to_filters(qp, opts \\ [])

Deserialize URL query parameters into a list of filters

example

Example

iex> "logic=and&genre=text%7Cindustrial%20metal&artist=text%7CDance%20With"
...> |> Filters.query_to_filters(keys: :atoms)
%Filters{
  filters: [
    %Filters.Filter{filter_type: :text, key: :genre, value: "industrial metal"},
    %Filters.Filter{filter_type: :text, key: :artist, value: "Dance With"}
  ],
  logic: :and
}