Belt_HashMap
A mutable Hash map which allows customized hash
behavior.
All data are parameterized by not its only type but also a unique identity in the time of initialization, so that two HashMaps of ints initialized with different hash functions will have different type.
For example:
type t = int module I0 = unpack(Belt.Id.hashableU(~hash=(. a: t) => "&"(a, 0xff_ff), ~eq=(. a, b) => a == b)) let s0: t<_, string, _> = make(~hintSize=40, ~id=module(I0)) module I1 = unpack(Belt.Id.hashableU(~hash=(. a: t) => "&"(a, 0xff), ~eq=(. a, b) => a == b)) let s1: t<_, string, _> = make(~hintSize=40, ~id=module(I1))
The invariant must be held: for two elements who are equal, their hashed value should be the same
Here the compiler would infer s0
and s1
having different type so that
it would not mix.
let s0: t<int, I0.identity> let s1: t<int, I1.identity>
We can add elements to the collection:
let () = { add(s1, 0, "3") add(s1, 1, "3") }
Since this is an mutable data strucure, s1
will contain two pairs.
undefined
Specalized when key type is int
, more efficient
than the generic type
module Int = Belt_HashMapInt
undefined
Specalized when key type is string
, more efficient
than the generic type
module String = Belt_HashMapString
t
The type of hash tables from type 'key
to type 'value
.
type t<'key, 'value, 'id>
id
The identity needed for making an empty hash map.
type id<'a, 'id> = Belt_Id.hashable<'a, 'id>
make
make(~hintSize=10, ~id)
creates a new map by taking in the comparator and hintSize
.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(hMap, 0, "a")
let make: (~hintSize: int, ~id: id<'key, 'id>) => t<'key, 'value, 'id>
clear
Clears a hash table.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let hMap = Belt.HashMap.fromArray([(1, "1")], ~id=module(IntHash))
Belt.HashMap.clear(hMap)
Belt.HashMap.isEmpty(hMap) == true
let clear: t<'key, 'value, 'id> => unit
isEmpty
isEmpty(m)
checks whether a hash map is empty.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
Belt.HashMap.isEmpty(Belt.HashMap.fromArray([(1, "1")], ~id=module(IntHash))) == false
let isEmpty: t<'a, 'b, 'c> => bool
set
set(hMap, k, v)
if k
does not exist, add the binding k,v
, otherwise, update the old value with the new v
.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntHash))
Belt.HashMap.set(s0, 2, "3")
Belt.HashMap.valuesToArray(s0) == ["1", "3", "3"]
let set: (t<'key, 'value, 'id>, 'key, 'value) => unit
copy
Creates copy of a hash map.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntHash))
let s1 = Belt.HashMap.copy(s0)
Belt.HashMap.set(s0, 2, "3")
Belt.HashMap.get(s0, 2) != Belt.HashMap.get(s1, 2)
let copy: t<'key, 'value, 'id> => t<'key, 'value, 'id>
get
Returns value bound under specific key. If values not exist returns None
.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.get(s0, 1) == Some("value1")
Belt.HashMap.get(s0, 2) == None
let get: (t<'key, 'value, 'id>, 'key) => option<'value>
has
Checks if x
is bound in tbl
.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.has(s0, 1) == true
Belt.HashMap.has(s0, 2) == false
let has: (t<'key, 'value, 'id>, 'key) => bool
remove
If bound exists, removes it from the hash map.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.remove(s0, 1)
Belt.HashMap.has(s0, 1) == false
let remove: (t<'key, 'value, 'id>, 'key) => unit
forEachU
Same as forEach but takes uncurried function.
let forEachU: (t<'key, 'value, 'id>, (. 'key, 'value) => unit) => unit
forEach
forEach(tbl, f)
applies f
to all bindings in table tbl
. f
receives the key as first argument, and the associated value as second argument. Each binding is presented exactly once to f
.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.forEach(s0, (key, value) => Js.log2(key, value))
// prints (1, "value1")
let forEach: (t<'key, 'value, 'id>, ('key, 'value) => unit) => unit
reduceU
let reduceU: (t<'key, 'value, 'id>, 'c, (. 'c, 'key, 'value) => 'c) => 'c
reduce
reduce(tbl, init, f)
computes (f(kN, dN) ... (f(k1, d1, init))...)
, where k1 ... kN
are the keys of all bindings in tbl
, and d1 ... dN
are the associated values. Each binding is presented exactly once to f
.
The order in which the bindings are passed to f
is unspecified. However, if the table contains several bindings for the same key, they are passed to f
in reverse order of introduction, that is, the most recent binding is passed first.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.set(s0, 2, "value2")
Belt.HashMap.reduce(s0, "", (acc, key, value) => acc ++ (", " ++ value)) == "value1, value2"
let reduce: (t<'key, 'value, 'id>, 'c, ('c, 'key, 'value) => 'c) => 'c
keepMapInPlaceU
Same as keepMapInPlace but takes uncurried function.
let keepMapInPlaceU: (t<'key, 'value, 'id>, (. 'key, 'value) => option<'value>) => unit
keepMapInPlace
Filters out values for which function f
returned None
.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.set(s0, 2, "value2")
Belt.HashMap.keepMapInPlace(s0, (key, value) => key == 1 ? None : Some(value))
let keepMapInPlace: (t<'key, 'value, 'id>, ('key, 'value) => option<'value>) => unit
size
size(tbl)
returns the number of bindings in tbl
. It takes constant time.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.set(s0, 2, "value2")
Belt.HashMap.size(s0) == 2
let size: t<'a, 'b, 'c> => int
toArray
Returns array of key value pairs.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.set(s0, 2, "value2")
Belt.HashMap.toArray(s0) == [(1, "value1"), (2, "value2")]
let toArray: t<'key, 'value, 'id> => array<('key, 'value)>
keysToArray
Returns array of keys.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.set(s0, 2, "value2")
Belt.HashMap.keysToArray(s0) == [1, 2]
let keysToArray: t<'key, 'a, 'b> => array<'key>
valuesToArray
Returns array of values.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(s0, 1, "value1")
Belt.HashMap.set(s0, 2, "value2")
Belt.HashMap.valuesToArray(s0) == ["value1", "value2"]
let valuesToArray: t<'a, 'value, 'b> => array<'value>
fromArray
Creates new hash map from array of pairs.
Returns array of values.
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let s0 = Belt.HashMap.fromArray([(1, "value1"), (2, "value2")], ~id=module(IntHash))
Belt.HashMap.toArray(s0) == [(1, "value1"), (2, "value2")]
let fromArray: (array<('key, 'value)>, ~id: id<'key, 'id>) => t<'key, 'value, 'id>
mergeMany
RESmodule IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.mergeMany(hMap, [(1, "1"), (2, "2")])
let mergeMany: (t<'key, 'value, 'id>, array<('key, 'value)>) => unit
getBucketHistogram
RES module IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(hMap, 1, "1")
Belt.HashMap.getBucketHistogram(hMap)
let getBucketHistogram: t<'a, 'b, 'c> => array<int>
logStats
RES module IntHash = Belt.Id.MakeHashable({
type t = int
let hash = a => a
let eq = (a, b) => a == b
})
let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash))
Belt.HashMap.set(hMap, 1, "1")
Belt.HashMap.logStats(hMap)
let logStats: t<'a, 'b, 'c> => unit