group_by now uses lists; a few more utils

This commit is contained in:
Simon Cruanes 2014-06-13 00:54:51 +02:00
parent 6ec499799c
commit 86cd5c0e8d
2 changed files with 24 additions and 14 deletions

View file

@ -260,25 +260,16 @@ module Map = struct
end end
| {eq=Some eq; hash=Some hash; _} -> make_hash ~eq ~hash () | {eq=Some eq; hash=Some hash; _} -> make_hash ~eq ~hash ()
let multiset build seq = let multimap build seq =
seq (fun (k,v) -> seq (fun (k,v) ->
build.update k (function build.update k (function
| None -> Some [v] | None -> Some [v]
| Some l -> Some (v::l))); | Some l -> Some (v::l)));
{ is_empty = build.cur.is_empty; build.cur
size = build.cur.size;
get = (fun k -> match build.cur.get k with
| None -> None
| Some v -> Some (Coll.of_list v));
fold = (fun f acc ->
build.cur.fold (fun acc k v -> f acc k (Coll.of_list v)) acc);
to_seq = build.cur.to_seq
|> CCSequence.map (fun (k,v) -> k,Coll.of_list v);
}
let multimap_cmp ?cmp seq = let multimap_cmp ?cmp seq =
let build = make_cmp ?cmp () in let build = make_cmp ?cmp () in
multiset build seq multimap build seq
let count build seq = let count build seq =
seq (fun x -> seq (fun x ->
@ -330,7 +321,7 @@ type (_, _) unary =
| Contains : 'a equal * 'a -> ('a collection, bool) unary | Contains : 'a equal * 'a -> ('a collection, bool) unary
| Get : ('b,'c) safety * 'a -> (('a,'b) Map.t, 'c) unary | Get : ('b,'c) safety * 'a -> (('a,'b) Map.t, 'c) unary
| GroupBy : 'b ord * ('a -> 'b) | GroupBy : 'b ord * ('a -> 'b)
-> ('a collection, ('b,'a collection) Map.t) unary -> ('a collection, ('b,'a list) Map.t) unary
| Count : 'a ord -> ('a collection, ('a, int) Map.t) unary | Count : 'a ord -> ('a collection, ('a, int) Map.t) unary
type ('a,'b,'key,'c) join_descr = { type ('a,'b,'key,'c) join_descr = {
@ -576,9 +567,15 @@ let map_to_list q =
let group_by ?(cmp=Pervasives.compare) f q = let group_by ?(cmp=Pervasives.compare) f q =
Unary (GroupBy (cmp,f), q) Unary (GroupBy (cmp,f), q)
let group_by' ?cmp f q =
map_iter (group_by ?cmp f q)
let count ?(cmp=Pervasives.compare) () q = let count ?(cmp=Pervasives.compare) () q =
Unary (Count cmp, q) Unary (Count cmp, q)
let count' ?cmp () q =
map_iter (count ?cmp () q)
let fold f acc q = let fold f acc q =
Unary (Fold (f, acc), q) Unary (Fold (f, acc), q)
@ -677,6 +674,9 @@ let diff ?(cmp=Pervasives.compare) () q1 q2 =
let fst q = map fst q let fst q = map fst q
let snd q = map snd q let snd q = map snd q
let map1 f q = map (fun (x,y) -> f x, y) q
let map2 f q = map (fun (x,y) -> x, f y) q
let flatten_opt q = filter_map _id q let flatten_opt q = filter_map _id q
let opt_get_exn q = let opt_get_exn q =

View file

@ -162,16 +162,21 @@ val map_to_list : ('a,'b) Map.t t -> ('a*'b) list t
(** {6 Aggregation} *) (** {6 Aggregation} *)
val group_by : ?cmp:'b ord -> val group_by : ?cmp:'b ord ->
('a -> 'b) -> 'a collection t -> ('b,'a collection) Map.t t ('a -> 'b) -> 'a collection t -> ('b,'a list) Map.t t
(** [group_by f] takes a collection [c] as input, and returns (** [group_by f] takes a collection [c] as input, and returns
a multimap [m] such that for each [x] in [c], a multimap [m] such that for each [x] in [c],
[x] occurs in [m] under the key [f x]. In other words, [f] is used [x] occurs in [m] under the key [f x]. In other words, [f] is used
to obtain a key from [x], and [x] is added to the multimap using this key. *) to obtain a key from [x], and [x] is added to the multimap using this key. *)
val group_by' : ?cmp:'b ord ->
('a -> 'b) -> 'a collection t -> ('b * 'a list) collection t
val count : ?cmp:'a ord -> unit -> 'a collection t -> ('a, int) Map.t t val count : ?cmp:'a ord -> unit -> 'a collection t -> ('a, int) Map.t t
(** [count c] returns a map from elements of [c] to the number (** [count c] returns a map from elements of [c] to the number
of time those elements occur. *) of time those elements occur. *)
val count' : ?cmp:'a ord -> unit -> 'a collection t -> ('a * int) collection t
val fold : ('b -> 'a -> 'b) -> 'b -> 'a collection t -> 'b t val fold : ('b -> 'a -> 'b) -> 'b -> 'a collection t -> 'b t
(** Fold over the collection *) (** Fold over the collection *)
@ -253,8 +258,13 @@ val diff : ?cmp:'a ord -> unit ->
(** Specialized projection operators *) (** Specialized projection operators *)
val fst : ('a * 'b) collection t -> 'a collection t val fst : ('a * 'b) collection t -> 'a collection t
val snd : ('a * 'b) collection t -> 'b collection t val snd : ('a * 'b) collection t -> 'b collection t
val map1 : ('a -> 'b) -> ('a * 'c) collection t -> ('b * 'c) collection t
val map2 : ('a -> 'b) -> ('c * 'a) collection t -> ('c * 'b) collection t
val flatten_opt : 'a option collection t -> 'a collection t val flatten_opt : 'a option collection t -> 'a collection t
(** Flatten the collection by removing options *) (** Flatten the collection by removing options *)