diff --git a/core/CCArray.ml b/core/CCArray.ml index 8d09c7b0..d91f555b 100644 --- a/core/CCArray.ml +++ b/core/CCArray.ml @@ -68,6 +68,13 @@ module type S = sig (** [find f a] returns [Some y] if there is an element [x] such that [f x = Some y], else it returns [None] *) + val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option + (** Like {!find}, but also pass the index to the predicate function. *) + + val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option + (** [find p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], + and [p x] holds. Otherwise returns [None] *) + val lookup : ?cmp:'a ord -> 'a -> 'a t -> int option (** Lookup the index of some value in a sorted array. @return [None] if the key is not present, or @@ -160,7 +167,7 @@ let rec _compare cmp a1 i1 j1 a2 i2 j2 = let rec _find f a i j = if i = j then None - else match f a.(i) with + else match f i a.(i) with | Some _ as res -> res | None -> _find f a (i+1) j @@ -290,8 +297,14 @@ let reverse_in_place a = *) let find f a = + _find (fun _ -> f ) a 0 (Array.length a) + +let findi f a = _find f a 0 (Array.length a) +let find_idx p a = + _find (fun i x -> if p x then Some (i,x) else None) a 0 (Array.length a) + let filter_map f a = let rec aux acc i = if i = Array.length a @@ -494,7 +507,12 @@ module Sub = struct Sub.reverse_in_place s; a = [| 1; 2; 5; 4; 3; 6 |] *) - let find f a = _find f a.arr a.i a.j + let find f a = _find (fun _ -> f) a.arr a.i a.j + + let findi f a = _find (fun i -> f (i-a.i)) a.arr a.i a.j + + let find_idx p a = + _find (fun i x -> if p x then Some (i,x) else None) a.arr a.i a.j let lookup_exn ?(cmp=Pervasives.compare) k a = _lookup_exn ~cmp k a.arr a.i (a.j-1) diff --git a/core/CCArray.mli b/core/CCArray.mli index 9025221c..ab975073 100644 --- a/core/CCArray.mli +++ b/core/CCArray.mli @@ -70,6 +70,13 @@ module type S = sig (** [find f a] returns [Some y] if there is an element [x] such that [f x = Some y], else it returns [None] *) + val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option + (** Like {!find}, but also pass the index to the predicate function. *) + + val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option + (** [find p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], + and [p x] holds. Otherwise returns [None] *) + val lookup : ?cmp:'a ord -> 'a -> 'a t -> int option (** Lookup the index of some value in a sorted array. @return [None] if the key is not present, or diff --git a/core/CCList.ml b/core/CCList.ml index 64d93a0c..cddb1911 100644 --- a/core/CCList.ml +++ b/core/CCList.ml @@ -234,19 +234,18 @@ let last n l = let len = List.length l in if len < n then l else drop (len-n) l -let find_idx p l = - let rec search i l = match l with - | [] -> None - | x::_ when p x -> Some (i, x) - | _::xs -> search (i+1) xs - in search 0 l +let findi f l = + let rec aux f i = function + | [] -> None + | x::l' -> + match f i x with + | Some _ as res -> res + | None -> aux f (i+1) l' + in aux f 0 l -let rec find f l = match l with - | [] -> None - | x::l' -> - match f x with - | Some _ as res -> res - | None -> find f l' +let find f l = findi (fun _ -> f) l + +let find_idx p l = findi (fun i x -> if p x then Some (i, x) else None) l (*$T find (fun x -> if x=3 then Some "a" else None) [1;2;3;4] = Some "a" diff --git a/core/CCList.mli b/core/CCList.mli index bd3c0ad7..f3c5f7af 100644 --- a/core/CCList.mli +++ b/core/CCList.mli @@ -88,15 +88,18 @@ val last : int -> 'a t -> 'a t (** [last n l] takes the last [n] elements of [l] (or less if [l] doesn't have that many elements *) -val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option -(** [find p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], - and [p x] holds. Otherwise returns [None] *) - val find : ('a -> 'b option) -> 'a t -> 'b option (** [find f l] traverses [l], applying [f] to each element. If for some element [x], [f x = Some y], then [Some y] is returned. Otherwise the call returns [None] *) +val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option +(** Like {!find}, but also pass the index to the predicate function. *) + +val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option +(** [find p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], + and [p x] holds. Otherwise returns [None] *) + val filter_map : ('a -> 'b option) -> 'a t -> 'b t (** Map and remove elements at the same time *)