mapped

An implementation of a Bidirectional Map in pure Gleam, using two Dicts.

Bidirectional Maps (or BiMaps) are useful when two sets of data map between each other in both directions.
For example, converting numbers to their word equivalents:

let numbers_to_words = mapped.from_list([
  #(1, "one")
  #(2, "two")
  #(3, "three")
  #(4, "four")
  #(5, "five")
])

let assert Ok(word) = mapped.get_by_left(4) // -> "four"
let assert Ok(number) = mapped.get_by_right("three") // -> 3

A single data structure can be used to perform both conversions.

Types

pub opaque type BiMap(left, right)

Functions

pub fn delete_by_left(
  from map: BiMap(a, b),
  remove key: a,
) -> BiMap(a, b)

Creates a new map from the given map, with all the same entries except for the one with the given left value, if it exists.

Examples

mapped.from_list([#("one", 1), #("two", 2), #("wrong", 83)]) |> mapped.delete_by_left("wrong")
// -> { "one" <> 1, "two" <> 2 }
mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.delete_by_left("three")
// -> { "one" <> 1, "two" <> 2 }
pub fn delete_by_right(
  from map: BiMap(a, b),
  remove key: b,
) -> BiMap(a, b)

Creates a new map from the given map, with all the same entries except for the one with the given right value, if it exists.

Examples

mapped.from_list(
  [#("one", 1), #("two", 2), #("wrong", 83)]
) |> mapped.delete_by_left("wrong")
// -> { "one" <> 1, "two" <> 2 }
mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.delete_by_left("three")
// -> { "one" <> 1, "two" <> 2 }
pub fn each(
  in map: BiMap(a, b),
  run callback: fn(a, b) -> c,
) -> Nil

Runs a function for each left-right pair in the map, discarding the result.

pub fn filter(
  in map: BiMap(a, b),
  keeping predicate: fn(a, b) -> Bool,
) -> BiMap(a, b)

Creates a new map from the given map, including only left-right pairs for which the given function returns true.

pub fn fold(
  over map: BiMap(a, b),
  from initial: c,
  with callback: fn(c, a, b) -> c,
) -> c

Iterates over the given map, folding the left and right values into a single value.

pub fn from_dict(dict: Dict(a, b)) -> BiMap(a, b)

Creates a map from a given dict, mapping the values of the dict to the keys as well.

Examples

dict.from_list([#("wibble", 1), #("wobble", 2)]) |> mapped.from_dict
// -> { "wibble" <> 1, "wobble" <> 2 }
pub fn from_list(list: List(#(a, b))) -> BiMap(a, b)

Creates a map from a list of tuples containing a left and right value.

Examples

mapped.from_list([#(1, 2), #(3, 4)])
// -> { 1 <> 2, 3 <> 4 }
pub fn get_by_left(
  from map: BiMap(a, b),
  get key: a,
) -> Result(b, Nil)

Returns the right value associated with this left value, if it exists.

Examples

mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.get_by_left("one")
// -> Ok(1)
mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.get_by_left("three")
// -> Error(Nil)
pub fn get_by_right(
  from map: BiMap(a, b),
  get key: b,
) -> Result(a, Nil)

Returns the left value associated with this right value, if it exists.

Examples

mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.get_by_right(2)
// -> Ok("two")
mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.get_by_right(14)
// -> Error(Nil)
pub fn has_left(map: BiMap(a, b), key: a) -> Bool

Returns whether the map contains an entry with the given left value.

Examples

mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.has_left("three")
// -> False
pub fn has_right(map: BiMap(a, b), key: b) -> Bool

Returns whether the map contains an entry with the given right value.

Examples

mapped.from_list([#("one", 1), #("two", 2)]) |> mapped.has_right(2)
// -> True
pub fn insert(
  into map: BiMap(a, b),
  left left: a,
  right right: b,
) -> BiMap(a, b)

Creates a new map from the given map, with all the same entries with an extra entry containing the left and right values provided.

If an entry already exists with the given left or right value, it is removed.

Examples

mapped.from_list([#(1, 2), #(3, 4)]) |> mapped.insert(5, 6)
// -> { 1 <> 2, 3 <> 4, 5 <> 6 }
mapped.from_list([#(1, 2), #(3, 4)]) |> mapped.insert(5, 4)
// -> { 1 <> 2, 5 <> 4 }
pub fn inspect(map: BiMap(a, b)) -> String

Converts a map to a string, allowing you to view its contents. This should only be used for debugging the contents of a map.

The output format of this is not guaranteed and may change any time.

pub fn left_to_right(map: BiMap(a, b)) -> Dict(a, b)

Creates a dict mapping the left values of the given map to te right values.

Examples

mapped.from_list([#("wibble", 1), #("wobble", 2)]) |> mapped.left_to_right
// -> dict.from_list([#("wibble", 1), #("wobble", 2)])
pub fn left_values(map: BiMap(a, b)) -> List(a)

Returns a list containing the left values of the given map.

The order of the resulting list is not guaranteed.

Examples

mapped.from_list([#("wibble", 1), #("wobble", 2)]) |> mapped.left_values
// -> ["wibble", "wobble"]
pub fn new() -> BiMap(a, b)

Creates an new empty map.

pub fn right_to_left(map: BiMap(a, b)) -> Dict(b, a)

Creates a dict mapping the right values of the given map to te left values.

Examples

mapped.from_list([#("wibble", 1), #("wobble", 2)]) |> mapped.right_to_left
// -> dict.from_list([#(1, "wibble"), #(2, "wobble")])
pub fn right_values(map: BiMap(a, b)) -> List(b)

Returns a list containing the right values of the given map.

The order of the resulting list is not guaranteed.

Examples

mapped.from_list([#("wibble", 1), #("wobble", 2)]) |> mapped.right_values
// -> [1, 2]
pub fn size(of map: BiMap(a, b)) -> Int

Returns the number of entries in the map. Runs in O(1) time.

Examples

mapped.from_list([#(1, 2), #(3, 4)]) |> mapped.size()
// -> 2
pub fn to_list(map: BiMap(a, b)) -> List(#(a, b))

Converts a map into a list of tuples containing the right and left values of each entry.

The order of the resulting list is not guaranteed.

Examples

mapped.new() |> mapped.to_list
// -> []
mapped.from_list([#(1, 2), #(3, 4)]) |> mapped.to_list
// -> [#(1, 2), #(3, 4)]
Search Document