a few more functions in CCVector, including in-place filtering

and efficient non-order-preserving removal
This commit is contained in:
Simon Cruanes 2014-06-15 19:36:15 +02:00
parent 90239f2c3e
commit d0393cd9b6
2 changed files with 47 additions and 6 deletions

View file

@ -42,6 +42,8 @@ type ('a,'mut) t = {
mutable vec : 'a array; mutable vec : 'a array;
} }
type 'a vector = ('a, rw) t
let freeze v = { let freeze v = {
size=v.size; size=v.size;
vec=v.vec; vec=v.vec;
@ -145,6 +147,14 @@ let set v i x =
if i < 0 || i >= v.size then failwith "Vector.set"; if i < 0 || i >= v.size then failwith "Vector.set";
Array.unsafe_set v.vec i x Array.unsafe_set v.vec i x
let remove v i =
if i < 0 || i >= v.size then failwith "Vector.remove";
(* if v.(i) not the last element, then put last element at index i *)
if i < v.size - 1
then v.vec.(i) <- v.vec.(v.size - 1);
(* remove one element *)
v.size <- v.size - 1
let append_seq a seq = let append_seq a seq =
seq (fun x -> push a x) seq (fun x -> push a x)
@ -251,6 +261,20 @@ let map f v =
vec=Array.map f v.vec vec=Array.map f v.vec
} }
let filter' p v =
let i = ref (v.size - 1) in
while !i >= 0 do
if not (p v.vec.(! i))
(* remove i-th item! *)
then remove v !i;
decr i
done
(*$T
let v = 1 -- 10 in filter' (fun x->x<4) v; \
to_list v |> List.sort Pervasives.compare = [1;2;3]
*)
let filter p v = let filter p v =
if _empty_array v if _empty_array v
then create () then create ()
@ -377,7 +401,7 @@ let of_seq ?(init=create ()) seq =
let to_seq v k = iter k v let to_seq v k = iter k v
let slice v start len = let slice_seq v start len =
assert (start >= 0 && len >= 0); assert (start >= 0 && len >= 0);
fun k -> fun k ->
assert (start+len < v.size); assert (start+len < v.size);
@ -387,9 +411,11 @@ let slice v start len =
done done
(*$T (*$T
slice (of_list [0;1;2;3;4]) 1 3 |> CCList.of_seq = [1;2;3] slice_seq (of_list [0;1;2;3;4]) 1 3 |> CCList.of_seq = [1;2;3]
*) *)
let slice v = (v.vec, 0, v.size)
let (--) i j = let (--) i j =
if i>j if i>j
then init (i-j+1) (fun k -> i-k) then init (i-j+1) (fun k -> i-k)

View file

@ -34,6 +34,9 @@ type ('a, 'mut) t
(** the type of a vector of elements of type ['a], with (** the type of a vector of elements of type ['a], with
a mutability flat ['mut] *) a mutability flat ['mut] *)
type 'a vector = ('a, rw) t
(** Type synonym: a ['a vector] is mutable. *)
type 'a sequence = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
type 'a gen = unit -> 'a option type 'a gen = unit -> 'a option
@ -110,10 +113,10 @@ val sort : ('a -> 'a -> int) -> ('a, _) t -> ('a, 'mut) t
(** Sort the vector *) (** Sort the vector *)
val sort' : ('a -> 'a -> int) -> ('a, rw) t -> unit val sort' : ('a -> 'a -> int) -> ('a, rw) t -> unit
(** sort the vector in place*) (** Sort the vector in place *)
val uniq_sort : ('a -> 'a -> int) -> ('a, rw) t -> unit val uniq_sort : ('a -> 'a -> int) -> ('a, rw) t -> unit
(** sort the array and remove duplicates in place*) (** Sort the array and remove duplicates, in place*)
val iter : ('a -> unit) -> ('a,_) t -> unit val iter : ('a -> unit) -> ('a,_) t -> unit
(** iterate on the vector *) (** iterate on the vector *)
@ -127,6 +130,10 @@ val map : ('a -> 'b) -> ('a,_) t -> ('b, 'mut) t
val filter : ('a -> bool) -> ('a,_) t -> ('a, 'mut) t val filter : ('a -> bool) -> ('a,_) t -> ('a, 'mut) t
(** filter elements from vector *) (** filter elements from vector *)
val filter' : ('a -> bool) -> ('a, rw) t -> unit
(** Filter elements in place. Does {b NOT} preserve the order
of the elements. *)
val fold : ('b -> 'a -> 'b) -> 'b -> ('a,_) t -> 'b val fold : ('b -> 'a -> 'b) -> 'b -> ('a,_) t -> 'b
(** fold on elements of the vector *) (** fold on elements of the vector *)
@ -164,6 +171,10 @@ val set : ('a, rw) t -> int -> 'a -> unit
(** access element, or (** access element, or
@raise Failure if bad index *) @raise Failure if bad index *)
val remove : ('a, rw) t -> int -> unit
(** Remove the [n-th] element of the vector. Does {b NOT} preserve the order
of the elements (might swap with the last element) *)
val rev : ('a,_) t -> ('a, 'mut) t val rev : ('a,_) t -> ('a, 'mut) t
(** Reverse the vector *) (** Reverse the vector *)
@ -196,8 +207,12 @@ val of_seq : ?init:('a,rw) t -> 'a sequence -> ('a, rw) t
val to_seq : ('a,_) t -> 'a sequence val to_seq : ('a,_) t -> 'a sequence
val slice : ('a,_) t -> int -> int -> 'a sequence val slice : ('a,rw) t -> ('a array * int * int)
(** [slice v start len] is the sequence of elements from [v.(start)] (** Vector as an array slice. By doing it we expose the internal array, so
be careful! *)
val slice_seq : ('a,_) t -> int -> int -> 'a sequence
(** [slice_seq v start len] is the sequence of elements from [v.(start)]
to [v.(start+len-1)]. *) to [v.(start+len-1)]. *)
val of_klist : ?init:('a, rw) t -> 'a klist -> ('a, rw) t val of_klist : ?init:('a, rw) t -> 'a klist -> ('a, rw) t