diff --git a/core/CCLinq.ml b/core/CCLinq.ml index 9728d414..c7803f00 100644 --- a/core/CCLinq.ml +++ b/core/CCLinq.ml @@ -137,6 +137,7 @@ module Coll = struct let sort cmp c = match c with | List l -> List (List.sort cmp l) + | Seq s -> List (List.sort cmp (CCSequence.to_rev_list s)) | _ -> to_seq c |> set_of_seq ~cmp @@ -228,7 +229,7 @@ module Map = struct M.fold (fun key set acc -> f acc key set) !map acc ); - to_seq = M.to_seq !map; + to_seq = (fun k -> M.to_seq !map k); } in { cur; @@ -281,11 +282,10 @@ module Map = struct let count build seq = seq (fun x -> - let n = match build.cur.get x with - | None -> 1 - | Some n -> n+1 - in - build.add x n); + build.update x + (function + | None -> Some 1 + | Some n -> Some (n+1))); build.cur let get m x = m.get x @@ -298,6 +298,8 @@ module Map = struct let size m = m.size () let to_seq m = m.to_seq + + let to_list m = m.to_seq |> CCSequence.to_rev_list end (** {2 Query operators} *) @@ -538,11 +540,15 @@ let flat_map_seq f q = let f' x = Coll.of_seq (f x) in Unary (FlatMap f', q) +let flat_map_list f q = + let f' x = Coll.of_list (f x) in + Unary (FlatMap f', q) + let take n q = Unary (Take n, q) let take_while p q = Unary (TakeWhile p, q) -let sort ~cmp q = Unary (Sort cmp, q) +let sort ?(cmp=Pervasives.compare) () q = Unary (Sort cmp, q) let distinct ?(cmp=Pervasives.compare) () q = Unary (Distinct cmp, q) @@ -553,10 +559,10 @@ let get key q = let get_exn key q = Unary (Get (Unsafe, key), q) -let map_to_seq q = +let map_iter q = Unary (GeneralMap (fun m -> Coll.of_seq m.Map.to_seq), q) -let map_to_seq_flatten q = +let map_iter_flatten q = let f m = m.Map.to_seq |> CCSequence.flatMap (fun (k,v) -> Coll.to_seq v |> CCSequence.map (fun v' -> k,v')) @@ -564,6 +570,9 @@ let map_to_seq_flatten q = in Unary (GeneralMap f, q) +let map_to_list q = + Unary (GeneralMap Map.to_list, q) + let group_by ?(cmp=Pervasives.compare) f q = Unary (GroupBy (cmp,f), q) @@ -704,3 +713,7 @@ let to_queue q = let to_stack q = QueryMap ((fun c s -> CCSequence.to_stack s (Coll.to_seq c)), q) + +(** {6 Misc} *) + +let run_list q = run (q |> to_list) diff --git a/core/CCLinq.mli b/core/CCLinq.mli index 885c8840..fec9860c 100644 --- a/core/CCLinq.mli +++ b/core/CCLinq.mli @@ -24,7 +24,25 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *) -(** {1 LINQ-like operations on collections} *) +(** {1 LINQ-like operations on collections} + +The purpose it to provide powerful combinators to express iteration, +transformation and combination of collections of items. + +{[ + +CCLinq.( + start_list [1;2;3] + |> flat_map_list (fun x -> CCList.(x -- (x+10))) + |> sort () + |> count () + |> map_to_list |> run +);; +- : (int * int) list = [(13, 1); (12, 2); (11, 3); (10, 3); (9, 3); + (8, 3); (7, 3); (6, 3); (5, 3); (4, 3); (3, 3); (2, 2); (1, 1)] +]} + +*) type 'a sequence = ('a -> unit) -> unit type 'a equal = 'a -> 'a -> bool @@ -49,6 +67,8 @@ module Map : sig val size : (_,_) t -> int val to_seq : ('a, 'b) t -> ('a * 'b) sequence + + val to_list : ('a, 'b) t -> ('a * 'b) list end (** {2 Query operators} *) @@ -79,6 +99,9 @@ val run : 'a t -> 'a val run_no_opt : 'a t -> 'a (** Execute the query, without optimizing it at all *) +val run_list : 'a collection t -> 'a list +(** Shortcut to obtain a list *) + (** {6 Basics on Collections} *) val map : ('a -> 'b) -> 'a collection t -> 'b collection t @@ -104,13 +127,15 @@ val flat_map : ('a -> 'b collection) -> 'a collection t -> 'b collection t val flat_map_seq : ('a -> 'b sequence) -> 'a collection t -> 'b collection t (** Same as {!flat_map} but using sequences *) +val flat_map_list : ('a -> 'b list) -> 'a collection t -> 'b collection t + val take : int -> 'a collection t -> 'a collection t (** take at most [n] elements *) val take_while : ('a -> bool) -> 'a collection t -> 'a collection t (** take elements while they satisfy a predicate *) -val sort : cmp:'a ord -> 'a collection t -> 'a collection t +val sort : ?cmp:'a ord -> unit -> 'a collection t -> 'a collection t (** Sort items by the given comparison function *) val distinct : ?cmp:'a ord -> unit -> 'a collection t -> 'a collection t @@ -126,12 +151,14 @@ val get_exn : 'a -> ('a, 'b) Map.t t -> 'b t (** Unsafe version of {!get}. @raise Not_found if the key is not present. *) -val map_to_seq : ('a,'b) Map.t t -> ('a*'b) collection t +val map_iter : ('a,'b) Map.t t -> ('a*'b) collection t (** View a multimap as a proper collection *) -val map_to_seq_flatten : ('a,'b collection) Map.t t -> ('a*'b) collection t +val map_iter_flatten : ('a,'b collection) Map.t t -> ('a*'b) collection t (** View a multimap as a collection of individual key/value pairs *) +val map_to_list : ('a,'b) Map.t t -> ('a*'b) list t + (** {6 Aggregation} *) val group_by : ?cmp:'b ord ->