View Source Idx (Idx v0.1.0)

Collection allowing access via dynamically created indices.

The API is similar to Map. See create_index/3 for more details about indices.

iex> users = [%{name: "Bob", age: 20}, %{name: "Eve", age: 27}, %{name: "John", age: 45}]
iex> idx = Idx.new(users, & &1.name)
iex> Idx.get(idx, "Bob")
%{name: "Bob", age: 20}
iex> idx |> Enum.to_list() |> Enum.sort()
users

Link to this section Summary

Types

Index function. Returns a key based on the value to be indexed. Must be pure (always return the same key for the same value).

t()

Functions

Creates a new non-primary index on the Idx instance.

Updates the value under the key by calling fun. No indices can change after the update.

Callback implementation for Access.fetch/2.

Allows accessing a value by a non-primary key in the idx.

Creates a new Idx instance.

Returns the primary key of a value under the given non-primary key.

Converts idx to a map, where keys are the primary keys of the idx.

Link to this section Types

@type full_key() :: primary_key() | non_primary_key()
@type index() :: (value() -> key())

Index function. Returns a key based on the value to be indexed. Must be pure (always return the same key for the same value).

@type index_name() :: atom()
@type key() :: any()
Link to this opaque

non_primary_key()

View Source (opaque)
@opaque non_primary_key()
@type primary_key() :: key()
@type t() :: %Idx{required(any()) => any()}
@type value() :: any()

Link to this section Functions

Link to this function

create_index(idx, name, fun, options \\ [])

View Source
@spec create_index(t(), index_name(), index(), [{:lazy?, boolean()}]) :: t()

Creates a new non-primary index on the Idx instance.

iex> users = [%{name: "Bob", age: 20}, %{name: "Eve", age: 27}, %{name: "John", age: 45}]
iex> idx = Idx.new(users, & &1.name)
iex> idx = Idx.create_index(idx, :initial, &String.first(&1.name))
iex> Idx.get(idx, Idx.key(:initial, "J"))
%{name: "John", age: 45}

If lazy option is set to true, the index keys won't be precomputed and stored, instead it will always be calculated on demand. This will slow down access, but speed up insertion and operations relying on other indices.

@spec drop_index(t(), index_name()) :: t()
Link to this function

fast_update!(idx, key, fun)

View Source
@spec fast_update!(t(), full_key(), (value() -> value())) :: t()

Updates the value under the key by calling fun. No indices can change after the update.

Thanks to the guarantee that the indices (including the primary index) won't change, this function is faster than update!/3. However, if the indices change, it will leave the idx in an invalid state and lead to undefined behaviour.

@spec fetch(t(), full_key()) :: {:ok, value()} | :error

Callback implementation for Access.fetch/2.

@spec fetch!(t(), full_key()) :: value()
Link to this function

get(idx, key, default \\ nil)

View Source
@spec get(t(), full_key(), value() | nil) :: value() | nil
Link to this function

get_and_update(idx, key, fun)

View Source
@spec get_and_update(t(), full_key(), (value() | nil -> {get, update} | :pop)) ::
  {get, t()}
when get: any(), update: value()

Callback implementation for Access.get_and_update/3.

Link to this function

get_and_update!(idx, key, fun)

View Source
@spec get_and_update!(t(), full_key(), (value() -> {get, update} | :pop)) ::
  {get, t()}
when get: any(), update: value()
@spec key(index_name(), non_primary_key()) :: full_key()

Allows accessing a value by a non-primary key in the idx.

See create_index/3 for details.

@spec member?(t(), value()) :: boolean()
Link to this function

new(enum \\ [], primary_index)

View Source
@spec new(Enumerable.t(), index()) :: t()

Creates a new Idx instance.

Link to this function

pop(idx, key, default \\ nil)

View Source
@spec pop!(t(), full_key()) :: value()
Link to this function

primary_key(idx, name, key)

View Source
@spec primary_key(t(), index_name(), non_primary_key()) ::
  {:ok, primary_key()} | :error

Returns the primary key of a value under the given non-primary key.

Link to this function

primary_key!(idx, name, key)

View Source
@spec primary_key!(t(), index_name(), non_primary_key()) :: primary_key()
@spec put(t(), value()) :: t()
@spec size(t()) :: non_neg_integer()
@spec to_list(t()) :: [value()]
@spec to_map(t()) :: %{required(key()) => value()}

Converts idx to a map, where keys are the primary keys of the idx.

@spec update!(t(), full_key(), (value() -> value())) :: t()