OrderedCollections.SortedMap (ordered_collections v0.3.3)
A sorted key-value store implemented using Erlang's :gb_trees
(Red-Black Trees).
This module stores items in sorted order by their keys and offers a rich set of features that allow it to integrate seamlessly with Elixir’s core protocols:
Enumerable: SortedMap implements the Enumerable protocol. This means you can use all the standard functions in the
Enum
module (likeEnum.map/2
,Enum.reduce/3
, andEnum.slice/2
) directly on a SortedMap.Example:
iex> map = SortedMap.new(%{b: 2, a: 1, c: 3}) iex> Enum.map(map, fn {k, v} -> {k, v * 2} end) [a: 2, b: 4, c: 6]
Collectable: SortedMap implements the Collectable protocol, allowing you to build a SortedMap from any enumerable using
Enum.into/2
.Example:
iex> map = Enum.into([{:a, 1}, {:b, 2}], SortedMap.new()) iex> SortedMap.to_list(map) [a: 1, b: 2]
Inspect: SortedMap implements the Inspect protocol, providing a clean and concise representation when you use
IO.inspect/1
.Example:
iex> map = SortedMap.new(%{b: 2, a: 1}) iex> captured = ExUnit.CaptureIO.capture_io(fn -> IO.inspect(map) end) iex> captured ~s(#SortedMap<%{a: 1, b: 2}>\n)
JSON Encoding: SortedMap implements the JSON.Encoder protocol (using the native JSON support in Elixir 1.18 and later). This ensures that when you encode a SortedMap to JSON, the keys appear in sorted order.
Example:
iex> map = SortedMap.new(%{a: 1, b: 2}) iex> JSON.encode!(map) ~s({"a":1,"b":2})
Implementation Details
Internally, SortedMap wraps Erlang's :gb_trees
to achieve efficient insertion, lookup, and deletion operations while automatically maintaining the order of keys. By leveraging the power of Erlang's native data structures and integrating with protocols like Enumerable, Collectable, Inspect, and JSON.Encoder, SortedMap behaves like a first-class Elixir collection with a familiar API.
Summary
Functions
Deletes a key.
Retrieves a value by key, returning a default if missing.
Checks if a key exists.
Returns the keys of the SortedMap in sorted order.
Returns the largest key. Returns :none
if the map is empty.
Merges two SortedMaps. In case of duplicate keys, values from the second map override those from the first.
Returns the smallest key. Returns :none
if the map is empty.
Creates a new empty sorted map.
Creates a new sorted map from a standard map.
Inserts a key-value pair, maintaining order.
Iterates over a range of keys, returning key-value pairs
whose keys are between min
and max
(inclusive).
Rebalances the tree.
Returns all key-value pairs in sorted order.
Converts the SortedMap
into a standard Map
, losing the sorted property.
Updates a key with a function. If the key doesn’t exist,
it is set to nil
.
Updates a key with a function. If the key doesn’t exist,
it sets it to default
.
Replaces the value for key
with new_value
if the key exists.
If key
does not exist, the map remains unchanged.
Returns the values of the SortedMap in the order corresponding to the sorted keys.
Types
@type non_empty_t() :: %OrderedCollections.SortedMap{tree: non_empty_tree()}
@type non_empty_tree() :: :gb_trees.tree()
@type t() :: %OrderedCollections.SortedMap{tree: :gb_trees.tree()}
Functions
Deletes a key.
Examples
iex> sm = SortedMap.new(%{a: 1, b: 2})
iex> sm2 = SortedMap.delete(sm, :b)
iex> SortedMap.has_key?(sm2, :b)
false
Retrieves a value by key, returning a default if missing.
Examples
iex> sm = SortedMap.new(%{a: 1})
iex> SortedMap.get(sm, :a)
1
iex> SortedMap.get(sm, :b, :default)
:default
Checks if a key exists.
Examples
iex> sm = SortedMap.new(%{a: 1, b: 2})
iex> SortedMap.has_key?(sm, :a)
true
iex> SortedMap.has_key?(sm, :c)
false
Returns the keys of the SortedMap in sorted order.
Examples
iex> sm = SortedMap.new(%{b: 2, a: 1, c: 3})
iex> SortedMap.keys(sm)
[:a, :b, :c]
Returns the largest key. Returns :none
if the map is empty.
Examples
iex> sm = SortedMap.new(%{b: 2, a: 1, c: 3})
iex> SortedMap.max_key(sm)
:c
iex> sm = SortedMap.new(%{b: 10, a: 99, c: 3})
iex> SortedMap.max_key(sm)
:c
iex> sm_empty = SortedMap.new()
iex> SortedMap.max_key(sm_empty)
:none
Merges two SortedMaps. In case of duplicate keys, values from the second map override those from the first.
Examples
iex> sm1 = SortedMap.new(%{a: 1, b: 2})
iex> sm2 = SortedMap.new(%{b: 3, c: 4})
iex> SortedMap.merge(sm1, sm2) |> SortedMap.to_list()
[{:a, 1}, {:b, 3}, {:c, 4}]
Returns the smallest key. Returns :none
if the map is empty.
Examples
iex> sm = SortedMap.new(%{b: 2, a: 1, c: 3})
iex> SortedMap.min_key(sm)
:a
iex> sm_empty = SortedMap.new()
iex> SortedMap.min_key(sm_empty)
:none
@spec new() :: t()
Creates a new empty sorted map.
Examples
iex> sm = SortedMap.new()
iex> SortedMap.to_map(sm)
%{}
Creates a new sorted map from a standard map.
Examples
iex> sm = SortedMap.new(%{a: 1, b: 2})
iex> SortedMap.get(sm, :a)
1
iex> SortedMap.get(sm, :b)
2
Inserts a key-value pair, maintaining order.
Examples
iex> sm = SortedMap.new(%{a: 1})
iex> sm = SortedMap.put(sm, :b, 2)
iex> SortedMap.get(sm, :b)
2
Iterates over a range of keys, returning key-value pairs
whose keys are between min
and max
(inclusive).
Examples
iex> sm = SortedMap.new(%{a: 1, b: 2, c: 3, d: 4})
iex> SortedMap.range(sm, :b, :c)
[{:b, 2}, {:c, 3}]
Rebalances the tree.
Examples
iex> sm = SortedMap.new(%{a: 1, b: 2, c: 3}) iex> smi = SortedMap.new() |> SortedMap.put(:a, 1) |> SortedMap.put(:b, 2) |> SortedMap.put(:c, 3) iex> sm == smi false iex> sm |> SortedMap.rebalance() == smi |> SortedMap.rebalance() true
Returns all key-value pairs in sorted order.
Examples
iex> sm = SortedMap.new(%{b: 2, a: 1})
iex> SortedMap.to_list(sm)
[{:a, 1}, {:b, 2}]
Converts the SortedMap
into a standard Map
, losing the sorted property.
Examples
iex> sm = SortedMap.new(%{b: 2, a: 1})
iex> SortedMap.to_map(sm)
%{a: 1, b: 2}
iex> sm = SortedMap.new(%{a: 2, b: 1})
iex> captured = ExUnit.CaptureIO.capture_io(fn -> IO.inspect(sm) end)
iex> captured
~s(#SortedMap<%{a: 2, b: 1}>\n)
iex> SortedMap.to_map(sm)
%{a: 2, b: 1}
Updates a key with a function. If the key doesn’t exist,
it is set to nil
.
Examples
iex> sm = SortedMap.new(%{a: 1})
iex> sm = SortedMap.update(sm, :a, &(&1 + 1))
iex> SortedMap.get(sm, :a)
2
iex> SortedMap.new(%{a: 1}) |> SortedMap.update(:b, &(&1 + 1)) |> SortedMap.get(:b)
nil
Updates a key with a function. If the key doesn’t exist,
it sets it to default
.
Examples
iex> sm = SortedMap.new(%{a: 1})
iex> sm = SortedMap.update(sm, :a, &(&1 + 5), 0)
iex> SortedMap.get(sm, :a)
6
iex> SortedMap.new(%{a: 1}) |> SortedMap.update(:b, &(&1 + 1), 10) |> SortedMap.get(:b)
10
Replaces the value for key
with new_value
if the key exists.
If key
does not exist, the map remains unchanged.
Examples
iex> sm = SortedMap.new(%{a: 1, b: 2})
iex> sm = SortedMap.update_with_value(sm, :a, 100)
iex> SortedMap.get(sm, :a)
100
iex> SortedMap.update_with_value(sm, :c, 300)
iex> SortedMap.get(sm, :c)
nil
Returns the values of the SortedMap in the order corresponding to the sorted keys.
Examples
iex> sm = SortedMap.new(%{b: 2, a: 1, c: 3})
iex> SortedMap.values(sm)
[1, 2, 3]