package tablecloth-native

  1. Overview
  2. Docs

A collection of key-value pairs

A Map represents a unique mapping from keys to values.

Map is an immutable data structure which means operations like Map.add and Map.remove do not modify the data structure, but return a new map with the desired changes.

Since maps of ints and strings are so common the specialized Map.Int and Map.String modules are available, which offer a convenient way to construct new maps.

Custom data types can be used with maps as long as the module satisfies the Comparator.S interface.

module Point = struct
  type t = int * int
  let compare = Tuple2.compare Int.compare Int.compare
  include Comparator.Make(struct
    type nonrec t = t
    let compare = compare
  end)
end

type animal = 
  | Cow
  | Pig
  | Alpacca

let pointToAnimal : animal Map.Of(Point).t = 
  Map.fromList (module Points) [((0, 0), Alpacca); ((3, 4), Cow); ((6, 7), Sheep)]

See the Comparator module for a more details.

type ('key, +'value, 'id) t = ('key, 'value, 'id) Base.Map.t
module Of (M : sig ... end) : sig ... end

This functor lets you describe the type of Maps a little more concisely.

Create

You can create sets of modules types which conform to the Comparator.S signature by using empty, singleton, fromList or fromArray.

Specialised versions of the empty, singleton, fromList and fromArray functions available in the Set.Int and Set.String sub-modules.

val empty : (module Tablecloth__.TableclothComparator.S with type identity = 'identity and type t = 'key) -> ('key, 'value, 'identity) t

A map with nothing in it.

Often used as an intial value for functions like Array.fold

Examples

Array.fold
  [|"Pear", "Orange", "Grapefruit"|]
  ~initial:(Map.empty (module Int))
  ~f:(fun lengthToFruit fruit ->
    Map.add lengthToFruit (String.length fruit) fruit
  )
|> Map.toArray
= [|(4, "Pear"); (6, "Orange"), (10, "Grapefruit")|]

In this particular case you might want to use Array.groupBy

val singleton : (module Tablecloth__.TableclothComparator.S with type identity = 'identity and type t = 'key) -> key:'key -> value:'value -> ('key, 'value, 'identity) t

Create a map from a key and value

Examples

Map.singleton (module Int) ~key:1 ~value:"Ant" |> Map.toList = [(1, "Ant")]
val fromArray : (module Tablecloth__.TableclothComparator.S with type identity = 'identity and type t = 'key) -> ('key * 'value) array -> ('key, 'value, 'identity) t

Create a map from an Array of key-value tuples

val from_array : (module Tablecloth__.TableclothComparator.S with type identity = 'identity and type t = 'key) -> ('key * 'value) array -> ('key, 'value, 'identity) t
val fromList : (module Tablecloth__.TableclothComparator.S with type identity = 'identity and type t = 'key) -> ('key * 'value) list -> ('key, 'value, 'identity) t

Create a map of a List of key-value tuples

val from_list : (module Tablecloth__.TableclothComparator.S with type identity = 'identity and type t = 'key) -> ('key * 'value) list -> ('key, 'value, 'identity) t

Basic operations

val add : ('key, 'value, 'id) t -> key:'key -> value:'value -> ('key, 'value, 'id) t

Adds a new entry to a map. If key is allready present, its previous value is replaced with value.

Examples

Map.add
  (Map.Int.fromList [(1, "Ant"); (2, "Bat")])
  ~key:3
  ~value:"Cat"
|> Map.toList = [(1, "Ant"); (2, "Bat"); (3, "Cat")]
Map.add (Map.Int.fromList [(1, "Ant"); (2, "Bat")]) ~key:2 ~value:"Bug" |> Map.toList = [(1, "Ant"); (2, "Bug")]
val (.?{}<-) : ('key, 'value, 'id) t -> 'key -> 'value -> ('key, 'value, 'id) t

The index operator version of add

Note Currently this is only supported by the OCaml syntax.

Examples

let indexToAnimal = Map.Int.fromList [(1, "Ant");(2, "Bat");(3, "Cat")] in
let indexToAnimal = numbers.Map.?{4} <- "Dog" in
indexToAnimal.Map.?{4} = Some "Dog"
val remove : ('key, 'value, 'id) t -> 'key -> ('key, 'value, 'id) t

Removes a key-value pair from a map based on they provided key.

Examples

let animalPopulations = Map.String.fromList [
  ("Elephant", 3_156);
  ("Mosquito", 56_123_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
] in
Map.remove animalPopulations "Mosquito" |> Map.toList = [
  ("Elephant", 3_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
]
val get : ('key, 'value, 'id) t -> 'key -> 'value option

Get the value associated with a key. If the key is not present in the map, returns None.

Examples

let animalPopulations = Map.String.fromList ("Elephant", 3_156); ("Mosquito", 56_123_156); ("Rhino", 3); ("Shrew", 56_423); in Map.get animalPopulations "Shrew" = Some 56_423;

val (.?{}) : ('key, 'value, _) t -> 'key -> 'value option

The index operator version of Map.get

Note Currently this is only supported by the OCaml syntax.

Examples

let indexToAnimal = Map.Int.fromList [(1, "Ant");(2, "Bat");(3, "Cat")] in
indexToAnimal.Map.?{3} = Some "Cat"
val update : ('key, 'value, 'id) t -> key:'key -> f:('value option -> 'value option) -> ('key, 'value, 'id) t

Update the value for a specific key using f. If key is not present in the map f will be called with None.

Examples

let animalPopulations = Map.String.fromList [
  ("Elephant", 3_156);
  ("Mosquito", 56_123_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
] in

Map.update animalPopulations ~key:"Hedgehog" ~f:(fun population ->
  match population with
  | None -> Some 1
  | Some count -> Some (count + 1)
)
|> Map.toList = [
  ("Elephant", 3_156);
  ("Hedgehog", 1);
  ("Mosquito", 56_123_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
]

Query

val isEmpty : (_, _, _) t -> bool

Determine if a map is empty.

val is_empty : (_, _, _) t -> bool
val length : (_, _, _) t -> int

Returns the number of key-value pairs present in the map.

Examples

Map.Int.fromList [(1, "Hornet"); (3, "Marmot")]
|> Map.length = 2
val any : (_, 'value, _) t -> f:('value -> bool) -> bool

Determine if f returns true for any values in a map.

val all : (_, 'value, _) t -> f:('value -> bool) -> bool

Determine if f returns true for all values in a map.

val find : ('key, 'value, _) t -> f:(key:'key -> value:'value -> bool) -> ('key * 'value) option

Returns, as an Option the first key-value pair for which f evaluates to true.

If f doesn't return true for any of the elements find will return None.

Searches starting from the smallest key

Examples

Map.String.fromList [
  ("Elephant", 3_156);
  ("Mosquito", 56_123_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
]
|> Map.find ~f:(fun ~key ~value -> value > 10_000)
  = Some ("Mosquito", 56_123_156)
val includes : ('key, _, _) t -> 'key -> bool

Determine if a map includes key.

val minimum : ('key, _, _) t -> 'key option

Returns, as an Option, the smallest key in the map.

Returns None if the map is empty.

Examples

Map.Int.fromList [(8, "Pigeon"); (1, "Hornet"); (3, "Marmot")]
|> Map.minimum = Some 1
val maximum : ('key, _, _) t -> 'key option

Returns the largest key in the map.

Returns None if the map is empty.

Examples

Map.Int.fromList [(8, "Pigeon"); (1, "Hornet"); (3, "Marmot")]
|> Map.maximum = Some 8
val extent : ('key, _, _) t -> ('key * 'key) option

Returns, as an Option, a Tuple of the (minimum, maximum) keys in the map.

Returns None if the map is empty.

Examples

Map.Int.fromList [(8, "Pigeon"); (1, "Hornet"); (3, "Marmot")]
|> Map.extent = Some (1, 8)

Combine

val merge : ('key, 'v1, 'id) t -> ('key, 'v2, 'id) t -> f:('key -> 'v1 option -> 'v2 option -> 'v3 option) -> ('key, 'v3, 'id) t

Combine two maps.

You provide a function f which is provided the key and the optional value from each map and needs to account for the three possibilities:

1. Only the 'left' map includes a value for the key. 2. Both maps contain a value for the key. 3. Only the 'right' map includes a value for the key.

You then traverse all the keys, building up whatever you want.

Examples

let animalToPopulation =
  Map.String.fromList [
    ("Elephant", 3_156);
    ("Shrew", 56_423);
  ]
in
let animalToPopulationGrowthRate = Map.String.fromList [
  ("Elephant", 0.88);
  ("Squirrel", 1.2);
  ("Python", 4.0);
] in

Map.merge
  animalToPopulation
  animalToPopulationGrowthRate
  ~f:(fun _animal population growth ->
    match (Option.both population growth) with
    | Some (population, growth) ->
        Some Float.((ofInt population) * growth)
    | None -> None
  )
|> Map.toList
  = [("Elephant", 2777.28)]

Transform

val map : ('key, 'value, 'id) t -> f:('value -> 'b) -> ('key, 'b, 'id) t

Apply a function to all values in a dictionary.

Examples

Map.String.fromList [
  ("Elephant", 3_156);
  ("Shrew", 56_423);
]
|> Map.map ~f:Int.toString
|> Map.toList
  = [
  ("Elephant", "3156");
  ("Shrew", "56423");
]
val mapWithIndex : ('key, 'value, 'id) t -> f:('key -> 'value -> 'b) -> ('key, 'b, 'id) t

Like map but f is also called with each values corresponding key

val map_with_index : ('key, 'value, 'id) t -> f:('key -> 'value -> 'b) -> ('key, 'b, 'id) t
val filter : ('key, 'value, 'id) t -> f:('value -> bool) -> ('key, 'value, 'id) t

Keep elements that f returns true for.

Examples

Map.String.fromList [
  ("Elephant", 3_156);
  ("Shrew", 56_423);
]
|> Map.map ~f:(fun population -> population > 10_000)
|> Map.toList
  = [
  ("Shrew", "56423");
]
val partition : ('key, 'value, 'id) t -> f:(key:'key -> value:'value -> bool) -> ('key, 'value, 'id) t * ('key, 'value, 'id) t

Divide a map into two, the first map will contain the key-value pairs that f returns true for, pairs that f returns false for will end up in the second.

Examples

let (endangered, notEndangered) = Map.String.fromList [
  ("Elephant", 3_156);
  ("Mosquito", 56_123_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
]
|> Map.partition ~f:(fun population -> population < 10_000)
in

Map.toList endangered = [
  ("Elephant", 3_156);
  ("Rhino", 3);
];

Map.toList notEndangered = [
  ("Mosquito", 56_123_156);
  ("Shrew", 56_423);
];
val fold : ('key, 'value, _) t -> initial:'a -> f:('a -> key:'key -> value:'value -> 'a) -> 'a

Like Array.fold but f is also called with both the key and value

Iterate

val forEach : (_, 'value, _) t -> f:('value -> unit) -> unit

Runs a function f against each value in the map.

val for_each : (_, 'value, _) t -> f:('value -> unit) -> unit
val forEachWithIndex : ('key, 'value, _) t -> f:(key:'key -> value:'value -> unit) -> unit

Like Map.forEach except ~f is also called with the corresponding key

val for_each_with_index : ('key, 'value, _) t -> f:(key:'key -> value:'value -> unit) -> unit

Convert

val keys : ('key, _, _) t -> 'key list

Get a List of all of the keys in a map.

Examples

Map.String.fromList [
  ("Elephant", 3_156);
  ("Mosquito", 56_123_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
]
|> Map.keys = [
  "Elephant";
  "Mosquito";
  "Rhino";
  "Shrew";
]
val values : (_, 'value, _) t -> 'value list

Get a List of all of the values in a map.

Examples

Map.String.fromList [
  ("Elephant", 3_156);
  ("Mosquito", 56_123_156);
  ("Rhino", 3);
  ("Shrew", 56_423);
]
|> Map.values = [
  3_156;
  56_123_156;
  3;
  56_423;
]
val toArray : ('key, 'value, _) t -> ('key * 'value) array

Get an Array of all of the key-value pairs in a map.

val to_array : ('key, 'value, _) t -> ('key * 'value) array
val toList : ('key, 'value, _) t -> ('key * 'value) list

Get a List of all of the key-value pairs in a map.

val to_list : ('key, 'value, _) t -> ('key * 'value) list
module Poly : sig ... end

Construct a Map which can be keyed by any data type using the polymorphic compare function.

module Int : sig ... end

Construct a Map with Ints for keys.

module String : sig ... end

Construct a Map with Strings for keys.