mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 19:55:31 -05:00
add CCHashtbl.update
This commit is contained in:
parent
1cc835dfd4
commit
c10b240474
2 changed files with 56 additions and 1 deletions
|
|
@ -71,6 +71,25 @@ let of_list l =
|
||||||
List.iter (fun (k,v) -> Hashtbl.add tbl k v) l;
|
List.iter (fun (k,v) -> Hashtbl.add tbl k v) l;
|
||||||
tbl
|
tbl
|
||||||
|
|
||||||
|
let update tbl ~f ~k =
|
||||||
|
let v = get tbl k in
|
||||||
|
match v, f k v with
|
||||||
|
| None, None -> ()
|
||||||
|
| None, Some v' -> Hashtbl.add tbl k v'
|
||||||
|
| Some _, Some v' -> Hashtbl.replace tbl k v'
|
||||||
|
| Some _, None -> Hashtbl.remove tbl k
|
||||||
|
|
||||||
|
(*$R
|
||||||
|
let tbl = Hashtbl.create 32 in
|
||||||
|
update tbl ~k:1 ~f:(fun _ _ -> Some "1");
|
||||||
|
assert_equal (Some "1") (get tbl 1);
|
||||||
|
update tbl ~k:2 ~f:(fun _ v->match v with Some _ -> assert false | None -> Some "2");
|
||||||
|
assert_equal (Some "2") (get tbl 2);
|
||||||
|
assert_equal 2 (Hashtbl.length tbl);
|
||||||
|
update tbl ~k:1 ~f:(fun _ _ -> None);
|
||||||
|
assert_equal None (get tbl 1);
|
||||||
|
*)
|
||||||
|
|
||||||
let print pp_k pp_v fmt m =
|
let print pp_k pp_v fmt m =
|
||||||
Format.fprintf fmt "@[<hov2>tbl {@,";
|
Format.fprintf fmt "@[<hov2>tbl {@,";
|
||||||
let first = ref true in
|
let first = ref true in
|
||||||
|
|
@ -121,10 +140,22 @@ module type S = sig
|
||||||
val of_list : (key * 'a) list -> 'a t
|
val of_list : (key * 'a) list -> 'a t
|
||||||
(** From the given list of bindings, added in order *)
|
(** From the given list of bindings, added in order *)
|
||||||
|
|
||||||
|
val update : 'a t -> f:(key -> 'a option -> 'a option) -> k:key -> unit
|
||||||
|
(** [update tbl ~f ~k] updates key [k] by calling [f k (Some v)] if
|
||||||
|
[k] was mapped to [v], or [f k None] otherwise; if the call
|
||||||
|
returns [None] then [k] is removed/stays removed, if the call
|
||||||
|
returns [Some v'] then the binding [k -> v'] is inserted
|
||||||
|
using {!Hashtbl.replace}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val print : key printer -> 'a printer -> 'a t printer
|
val print : key printer -> 'a printer -> 'a t printer
|
||||||
|
(** Printer for tables
|
||||||
|
@since 0.13 *)
|
||||||
end
|
end
|
||||||
|
|
||||||
module Make(X : Hashtbl.HashedType) = struct
|
module Make(X : Hashtbl.HashedType)
|
||||||
|
: S with type key = X.t and type 'a t = 'a Hashtbl.Make(X).t
|
||||||
|
= struct
|
||||||
include Hashtbl.Make(X)
|
include Hashtbl.Make(X)
|
||||||
|
|
||||||
let get tbl x =
|
let get tbl x =
|
||||||
|
|
@ -143,6 +174,14 @@ module Make(X : Hashtbl.HashedType) = struct
|
||||||
(fun x y acc -> f x y :: acc)
|
(fun x y acc -> f x y :: acc)
|
||||||
h []
|
h []
|
||||||
|
|
||||||
|
let update tbl ~f ~k =
|
||||||
|
let v = get tbl k in
|
||||||
|
match v, f k v with
|
||||||
|
| None, None -> ()
|
||||||
|
| None, Some v' -> add tbl k v'
|
||||||
|
| Some _, Some v' -> replace tbl k v'
|
||||||
|
| Some _, None -> remove tbl k
|
||||||
|
|
||||||
let to_seq tbl k = iter (fun key v -> k (key,v)) tbl
|
let to_seq tbl k = iter (fun key v -> k (key,v)) tbl
|
||||||
|
|
||||||
let of_seq seq =
|
let of_seq seq =
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,14 @@ val to_list : ('a,'b) Hashtbl.t -> ('a * 'b) list
|
||||||
val of_list : ('a * 'b) list -> ('a,'b) Hashtbl.t
|
val of_list : ('a * 'b) list -> ('a,'b) Hashtbl.t
|
||||||
(** From the given list of bindings, added in order *)
|
(** From the given list of bindings, added in order *)
|
||||||
|
|
||||||
|
val update : ('a, 'b) Hashtbl.t -> f:('a -> 'b option -> 'b option) -> k:'a -> unit
|
||||||
|
(** [update tbl ~f ~k] updates key [k] by calling [f k (Some v)] if
|
||||||
|
[k] was mapped to [v], or [f k None] otherwise; if the call
|
||||||
|
returns [None] then [k] is removed/stays removed, if the call
|
||||||
|
returns [Some v'] then the binding [k -> v'] is inserted
|
||||||
|
using {!Hashtbl.replace}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val print : 'a printer -> 'b printer -> ('a, 'b) Hashtbl.t printer
|
val print : 'a printer -> 'b printer -> ('a, 'b) Hashtbl.t printer
|
||||||
(** Printer for table
|
(** Printer for table
|
||||||
@since 0.13 *)
|
@since 0.13 *)
|
||||||
|
|
@ -109,6 +117,14 @@ module type S = sig
|
||||||
val of_list : (key * 'a) list -> 'a t
|
val of_list : (key * 'a) list -> 'a t
|
||||||
(** From the given list of bindings, added in order *)
|
(** From the given list of bindings, added in order *)
|
||||||
|
|
||||||
|
val update : 'a t -> f:(key -> 'a option -> 'a option) -> k:key -> unit
|
||||||
|
(** [update tbl ~f ~k] updates key [k] by calling [f k (Some v)] if
|
||||||
|
[k] was mapped to [v], or [f k None] otherwise; if the call
|
||||||
|
returns [None] then [k] is removed/stays removed, if the call
|
||||||
|
returns [Some v'] then the binding [k -> v'] is inserted
|
||||||
|
using {!Hashtbl.replace}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val print : key printer -> 'a printer -> 'a t printer
|
val print : key printer -> 'a printer -> 'a t printer
|
||||||
(** Printer for tables
|
(** Printer for tables
|
||||||
@since 0.13 *)
|
@since 0.13 *)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue