From e530547356f9b6a5cf9caeb4b90320cb45ec3382 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Thu, 26 Jul 2018 04:39:06 -0500 Subject: [PATCH] feat(vector): add `Vector.{filter,filter_map}_in_place` --- src/core/CCVector.ml | 41 +++++++++++++++++++++++++++++++++++++++++ src/core/CCVector.mli | 8 ++++++++ 2 files changed, 49 insertions(+) diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index 696c2bc1..cf19390b 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -483,6 +483,24 @@ let map f v = to_list (map string_of_int v) = ["1"; "2"; "3"] *) +(*$QR + Q.(pair (fun1 Observable.int small_int) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + to_list (map f v) = List.map f l) +*) + +let map_in_place f v = + iteri + (fun i x -> Array.unsafe_set v.vec i (f x)) + v + +(*$QR + Q.(pair (fun1 Observable.int small_int) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + map_in_place f v; + to_list v = List.map f l) +*) + let filter' p v = let i = ref 0 in (* cur element *) let j = ref 0 in (* cur insertion point *) @@ -638,6 +656,29 @@ let filter_map f v = to_list (filter_map f v) = CCList.filter_map f l) *) +let filter_map_in_place f v = + let i = ref 0 in (* cur element *) + let j = ref 0 in (* cur insertion point *) + let n = v.size in + while !i < n do + match f v.vec.(!i) with + | None -> incr i (* drop *) + | Some y -> + (* move element i at the first empty slot. + invariant: i >= j*) + v.vec.(!j) <- y; + incr i; + incr j + done; + v.size <- !j + +(*$QR + Q.(pair (fun1 Observable.int (option small_int)) (small_list small_int)) (fun (Q.Fun (_,f),l) -> + let v = of_list l in + filter_map_in_place f v; + to_list v = CCList.filter_map f l) +*) + let flat_map f v = let v' = create () in iter (fun x -> iter (push v') (f x)) v; diff --git a/src/core/CCVector.mli b/src/core/CCVector.mli index 3b1f4f17..80ed0a2f 100644 --- a/src/core/CCVector.mli +++ b/src/core/CCVector.mli @@ -141,6 +141,10 @@ val iteri : (int -> 'a -> unit) -> ('a,_) t -> unit val map : ('a -> 'b) -> ('a,_) t -> ('b, 'mut) t (** Map elements of the vector, yielding a new vector. *) +val map_in_place : ('a -> 'a) -> ('a,_) t -> unit +(** Map elements of the vector in place + @since NEXT_RELEASE *) + val filter : ('a -> bool) -> ('a,_) t -> ('a, 'mut) t (** Filter elements from the vector. [filter p v] leaves [v] unchanged but returns a new vector that only contains elements of [v] satisfying [p]. *) @@ -172,6 +176,10 @@ val find_map : ('a -> 'b option) -> ('a,_) t -> 'b option val filter_map : ('a -> 'b option) -> ('a,_) t -> ('b, 'mut) t (** Map elements with a function, possibly filtering some of them out. *) +val filter_map_in_place : ('a -> 'a option) -> ('a,_) t -> unit +(** Filter-map elements of the vector in place + @since NEXT_RELEASE *) + val flat_map : ('a -> ('b,_) t) -> ('a,_) t -> ('b, 'mut) t (** Map each element to a sub-vector. *)