From 799089659a3302c4435834865b8afdb2f8b6a7aa Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Wed, 21 Oct 2015 14:15:33 +0200 Subject: [PATCH] add `CCVector.find_map` --- src/core/CCVector.ml | 21 ++++++++++++++++++++- src/core/CCVector.mli | 5 +++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index 2745f2b6..2254a04d 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -454,7 +454,9 @@ let find_exn p v = let n = v.size in let rec check i = if i = n then raise Not_found - else if p v.vec.(i) then v.vec.(i) + else + let x = v.vec.(i) in + if p x then x else check (i+1) in check 0 @@ -462,6 +464,23 @@ let find p v = try Some (find_exn p v) with Not_found -> None +let find_map f v = + let n = v.size in + let rec search i = + if i=n then None + else match f v.vec.(i) with + | None -> search (i+1) + | Some _ as res -> res + in + search 0 + +(*$Q + Q.(list small_int) (fun l -> \ + let v = of_list l in \ + let f x = x>30 && x < 35 in \ + find_map (fun x -> if f x then Some x else None) v = find f v) +*) + let filter_map f v = let v' = create () in iter diff --git a/src/core/CCVector.mli b/src/core/CCVector.mli index 3c5976f8..26871405 100644 --- a/src/core/CCVector.mli +++ b/src/core/CCVector.mli @@ -164,6 +164,11 @@ val find_exn : ('a -> bool) -> ('a,_) t -> 'a (** find an element that satisfies the predicate, or @raise Not_found if no element does *) +val find_map : ('a -> 'b option) -> ('a,_) t -> 'b option +(** [find_map f v] returns the first [Some y = f x] for [x] in [v], + or [None] if [f x = None] for each [x] in [v] + @since NEXT_RELEASE *) + val filter_map : ('a -> 'b option) -> ('a,_) t -> ('b, 'mut) t (** Map elements with a function, possibly filtering some of them out *)