OrderedCollections.SortedSet (ordered_collections v0.3.3)

A sorted set implemented using Erlang's :gb_sets.

This module provides a sorted set data structure that stores unique elements in sorted order. Internally, it wraps Erlang's :gb_sets to provide efficient operations (insertion, deletion, and membership checking). SortedSet is designed to integrate seamlessly with Elixir's core protocols, making it behave like a first-class Elixir collection.

Protocol Support

  • Enumerable: SortedSet implements the Enumerable protocol. This means you can traverse the set using functions like Enum.map/2, Enum.reduce/3, and Enum.slice/2, all while preserving the sorted order of elements.

    Example:

    iex> set = SortedSet.new([3, 1, 2])
    iex> Enum.map(set, &(&1 * 2))
    [2, 4, 6]
  • Collectable: SortedSet implements the Collectable protocol, allowing you to build a SortedSet from any enumerable using Enum.into/2.

    Example:

    iex> set = Enum.into([3, 1, 2], SortedSet.new())
    iex> SortedSet.to_list(set)
    [1, 2, 3]
  • Inspect: SortedSet implements the Inspect protocol, providing a clean and readable output when you use IO.inspect/1.

    Example:

    iex> set = SortedSet.new([3, 1, 2])
    iex> captured = ExUnit.CaptureIO.capture_io(fn -> IO.inspect(set) end)
    iex> captured
    ~s(#SortedSet<[1, 2, 3]>\n)
  • JSON Encoding: SortedSet implements the JSON.Encoder protocol (using Elixir 1.18's native JSON support) so that when you encode a SortedSet to JSON, it is represented as an array with the elements in sorted order.

    Example:

    iex> set = SortedSet.new([3, 1, 2])
    iex> JSON.encode!(set)
    "[1,2,3]"

Implementation Details

Internally, SortedSet leverages Erlang's :gb_sets to maintain a sorted collection of unique elements. By integrating with Enumerable, Collectable, Inspect, and JSON.Encoder, SortedSet provides a natural, idiomatic API that behaves just like other Elixir collections while preserving the sorted order of its elements.

Summary

Functions

Adds a value to the SortedSet.

Deletes a value from the SortedSet.

Returns a new SortedSet that contains elements in the first set that are not present in the second.

Folds over the elements of a SortedSet in sorted order.

Returns a new SortedSet that contains elements present in both sets.

Returns the maximum element of the SortedSet.

Checks if a value is a member of the SortedSet.

Returns the minimum element of the SortedSet.

Creates a new empty SortedSet.

Creates a new SortedSet from a list.

Returns a list of elements in the SortedSet that fall within the given range (inclusive).

Converts the SortedSet into a list of elements in sorted order.

Returns a new SortedSet that is the union of two SortedSets.

Types

element()

@type element() :: any()

non_empty_set()

@type non_empty_set() :: :gb_sets.set()

non_empty_t()

@type non_empty_t() :: %OrderedCollections.SortedSet{set: non_empty_set()}

t()

@opaque t()

Functions

add(sorted_set, value)

@spec add(t(), element()) :: t()

Adds a value to the SortedSet.

Returns the set unchanged if the item already exists in the set

Examples

iex> set = OrderedCollections.SortedSet.new([2, 3])
iex> set = OrderedCollections.SortedSet.add(set, 1)
iex> set = OrderedCollections.SortedSet.add(set, 3)
iex> OrderedCollections.SortedSet.to_list(set)
[1, 2, 3]

delete(sorted_set, value)

@spec delete(t(), element()) :: t()

Deletes a value from the SortedSet.

Examples

iex> set = OrderedCollections.SortedSet.new([1, 2, 3])
iex> set = OrderedCollections.SortedSet.delete(set, 2)
iex> OrderedCollections.SortedSet.to_list(set)
[1, 3]

difference(sorted_set1, sorted_set2)

@spec difference(t(), t()) :: t()

Returns a new SortedSet that contains elements in the first set that are not present in the second.

Examples

iex> set1 = OrderedCollections.SortedSet.new([1, 2, 3, 4, 5])
iex> set2 = OrderedCollections.SortedSet.new([2, 4])
iex> OrderedCollections.SortedSet.difference(set1, set2) |> OrderedCollections.SortedSet.to_list()
[1, 3, 5]

fold(sorted_set, acc, fun)

@spec fold(t(), any(), (element(), any() -> any())) :: any()

Folds over the elements of a SortedSet in sorted order.

Examples

iex> set = OrderedCollections.SortedSet.new([1, 2, 3])
iex> OrderedCollections.SortedSet.fold(set, 0, &+/2)
6

intersection(sorted_set1, sorted_set2)

@spec intersection(t(), t()) :: t()

Returns a new SortedSet that contains elements present in both sets.

Examples

iex> set1 = SortedSet.new([1, 2, 3])
iex> set2 = SortedSet.new([2, 3, 4])
iex> SortedSet.intersection(set1, set2) |> SortedSet.to_list()
[2, 3]

max(sorted_set)

@spec max(non_empty_t()) :: element()

Returns the maximum element of the SortedSet.

Examples

iex> set = OrderedCollections.SortedSet.new([3, 1, 2])
iex> OrderedCollections.SortedSet.max(set)
3

member?(sorted_set, value)

@spec member?(t(), element()) :: boolean()

Checks if a value is a member of the SortedSet.

Examples

iex> set = OrderedCollections.SortedSet.new([1, 2, 3])
iex> OrderedCollections.SortedSet.member?(set, 2)
true
iex> OrderedCollections.SortedSet.member?(set, 4)
false

min(sorted_set)

@spec min(non_empty_t()) :: element()

Returns the minimum element of the SortedSet.

Examples

iex> set = OrderedCollections.SortedSet.new([3, 1, 2])
iex> OrderedCollections.SortedSet.min(set)
1

new()

@spec new() :: t()

Creates a new empty SortedSet.

Examples

iex> set = OrderedCollections.SortedSet.new()
iex> OrderedCollections.SortedSet.to_list(set)
[]

new(list)

@spec new(list()) :: t()

Creates a new SortedSet from a list.

Examples

iex> set = OrderedCollections.SortedSet.new([3, 1, 2])
iex> OrderedCollections.SortedSet.to_list(set)
[1, 2, 3]

iex> map_set = MapSet.new([3, 1, 2])
iex> OrderedCollections.SortedSet.new(map_set)
#SortedSet<[1, 2, 3]>

range(sorted_set, min, max)

@spec range(t(), element(), element()) :: t()

Returns a list of elements in the SortedSet that fall within the given range (inclusive).

Examples

iex> set = OrderedCollections.SortedSet.new([1, 2, 3, 4, 5])
iex> OrderedCollections.SortedSet.range(set, 2, 4) |> OrderedCollections.SortedSet.to_list()
[2, 3, 4]

to_list(sorted_set)

@spec to_list(t()) :: list()

Converts the SortedSet into a list of elements in sorted order.

Examples

iex> set = OrderedCollections.SortedSet.new([3, 1, 2])
iex> OrderedCollections.SortedSet.to_list(set)
[1, 2, 3]

union(sorted_set1, sorted_set2)

@spec union(t(), t()) :: t()

Returns a new SortedSet that is the union of two SortedSets.

Examples

iex> set1 = OrderedCollections.SortedSet.new([1, 3, 5])
iex> set2 = OrderedCollections.SortedSet.new([2, 3, 4])
iex> OrderedCollections.SortedSet.union(set1, set2) |> OrderedCollections.SortedSet.to_list()
[1, 2, 3, 4, 5]