mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 03:05:29 -05:00
add {union,inter,diff,subset}
This commit is contained in:
parent
6c7d59042a
commit
40f33f6f96
2 changed files with 90 additions and 0 deletions
|
|
@ -613,6 +613,52 @@ let group_join_by (type a) ?(eq=(=)) ?(hash=Hashtbl.hash) f c1 c2 =
|
|||
|> sort |> to_list)
|
||||
*)
|
||||
|
||||
let union (type a) ?(eq=(=)) ?(hash=Hashtbl.hash) c1 c2 =
|
||||
let module Tbl = Hashtbl.Make(struct
|
||||
type t = a let equal = eq let hash = hash end) in
|
||||
let tbl = Tbl.create 32 in
|
||||
c1 (fun x -> Tbl.replace tbl x ());
|
||||
c2 (fun x -> Tbl.replace tbl x ());
|
||||
fun yield -> Tbl.iter (fun x _ -> yield x) tbl
|
||||
|
||||
type inter_status =
|
||||
| Inter_left
|
||||
| Inter_both
|
||||
|
||||
let inter (type a) ?(eq=(=)) ?(hash=Hashtbl.hash) c1 c2 =
|
||||
let module Tbl = Hashtbl.Make(struct
|
||||
type t = a let equal = eq let hash = hash end) in
|
||||
let tbl = Tbl.create 32 in
|
||||
c1 (fun x -> Tbl.replace tbl x Inter_left);
|
||||
c2
|
||||
(fun x ->
|
||||
try
|
||||
match Tbl.find tbl x with
|
||||
| Inter_left ->
|
||||
Tbl.replace tbl x Inter_both; (* save *)
|
||||
| Inter_both -> ()
|
||||
with Not_found -> ());
|
||||
fun yield -> Tbl.iter (fun x res -> if res=Inter_both then yield x) tbl
|
||||
|
||||
let diff (type a) ?(eq=(=)) ?(hash=Hashtbl.hash) c1 c2 =
|
||||
let module Tbl = Hashtbl.Make(struct
|
||||
type t = a let equal = eq let hash = hash end) in
|
||||
let tbl = Tbl.create 32 in
|
||||
c2 (fun x -> Tbl.replace tbl x ());
|
||||
fun yield ->
|
||||
c1 (fun x -> if not (Tbl.mem tbl x) then yield x)
|
||||
|
||||
exception Subset_exit
|
||||
|
||||
let subset (type a) ?(eq=(=)) ?(hash=Hashtbl.hash) c1 c2 =
|
||||
let module Tbl = Hashtbl.Make(struct
|
||||
type t = a let equal = eq let hash = hash end) in
|
||||
let tbl = Tbl.create 32 in
|
||||
c2 (fun x -> Tbl.replace tbl x ());
|
||||
try
|
||||
c1 (fun x -> if not (Tbl.mem tbl x) then raise Subset_exit);
|
||||
true
|
||||
with Subset_exit -> false
|
||||
|
||||
let rec unfoldr f b k = match f b with
|
||||
| None -> ()
|
||||
|
|
|
|||
|
|
@ -331,6 +331,50 @@ val group_join_by : ?eq:'a equal -> ?hash:'a hash ->
|
|||
are mapped to [[]]
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val inter :
|
||||
?eq:'a equal -> ?hash:'a hash ->
|
||||
'a t -> 'a t -> 'a t
|
||||
(** Intersection of two collections. Each element will occur at most once
|
||||
in the result. Eager.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
(*$=
|
||||
[2;4;5;6] (inter (1--6) (cons 2 (4--10)) |> sort |> to_list)
|
||||
[] (inter (0--5) (6--10) |> to_list)
|
||||
*)
|
||||
|
||||
val union :
|
||||
?eq:'a equal -> ?hash:'a hash ->
|
||||
'a t -> 'a t -> 'a t
|
||||
(** Union of two collections. Each element will occur at most once
|
||||
in the result. Eager.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
(*$=
|
||||
[2;4;5;6] (union (4--6) (cons 2 (4--5)) |> sort |> to_list)
|
||||
*)
|
||||
|
||||
val diff :
|
||||
?eq:'a equal -> ?hash:'a hash ->
|
||||
'a t -> 'a t -> 'a t
|
||||
(** Set difference. Eager.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
(*$=
|
||||
[1;2;8;9;10] (diff (1--10) (3--7) |> to_list)
|
||||
*)
|
||||
|
||||
val subset :
|
||||
?eq:'a equal -> ?hash:'a hash ->
|
||||
'a t -> 'a t -> bool
|
||||
(** [subset a b] returns [true] if all elements of [a] belong to [b]. Eager.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
(*$T
|
||||
subset (2 -- 4) (1 -- 4)
|
||||
not (subset (1 -- 4) (2 -- 10))
|
||||
*)
|
||||
|
||||
val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
|
||||
(** [unfoldr f b] will apply [f] to [b]. If it
|
||||
yields [Some (x,b')] then [x] is returned
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue