For many students of ocaml, using hashtables is complicated by the functors. Here are a few tips:
For a list of hashtable functions see Hashtbl_intf.S
.
To create a hashtable with string keys use String.Table.
let table = String.Table.create () ~size:4 in
List.iter ~f:(fun (key, data) -> Hashtbl.set table ~key ~data)
[ ("A", 1); ("B", 2); ("C", 3); ];
Hashtbl.find table "C"
Here 4 need only be a guess at the hashtable's future size. There are other similar pre-made hashtables, eg Int63.Table or Host_and_port.Table.
To create a hashtable with a custom key type use Hashable.
module Key = struct
module T = struct
type t = String.t * Int63.t [@@deriving sexp]
let compare = compare
let hash = Hashtbl.hash
end
include T
include Hashable.Make (T)
end
let table = Key.Table.create () ~size:4 in
List.iter ~f:(fun (key, data) -> Hashtbl.set table ~key ~data)
[ (("pi", Int63.zero), 3.14159);
(("e", Int63.minus_one), 2.71828);
(("Euler", Int63.one), 0.577215);
];
Hashtbl.find table ("pi", Int63.zero)
Performance may improve if you define equal
and hash
explicitly, eg:
let equal (x, y) (x', y') = String.(=) x x' && Int63.(=) y y'
let hash (x, y) = String.hash x + Int63.hash y * 65599
We use [@@deriving sexp_of]
but not [@@deriving sexp]
because we want people to
be explicit about the hash and comparison functions used when creating hashtables.
One can use Hashtbl.Poly.t
, which does have [@@deriving sexp]
, to use
polymorphic comparison and hashing.
create_mapped get_key get_data [x1,...,xn]
= of_alist [get_key x1, get_data x1; ...; get_key xn, get_data xn]
create_with_key ~get_key [x1,...,xn]
= of_alist [get_key x1, x1; ...; get_key xn, xn]
like filter_map
, but function takes both key and data as arguments
returns new maps with bound values partitioned by f applied to the bound values
like partition_map
, but function takes both key and data as arguments
Merge two hashtables.
The result of merge f h1 h2
has as keys the set of all k
in the
union of the sets of keys of h1
and h2
for which d(k)
is not
None, where:
d(k) =
k
in h1
is to d1, and h2
does not map k
;k
in h2
is to d2, and h1
does not map k
;k
in h1
is to d1
and k
in h2
is to d2
.Each key k
is mapped to a single piece of data x, where d(k)
= Some x.
Returns the list of all data for given hashtable.
filter_inplace t ~f
removes all the elements from t
that don't satisfy f
.
replace_all t ~f
applies f to all elements in t
, transforming them in place
filter_replace_all
combines the effects of replace_all
and filter_inplace