Add List.findi, Array.findi and Array.find_idx.

This commit is contained in:
Drup 2014-08-08 17:54:47 +02:00
parent 8f46630634
commit 7c9eb7dfab
4 changed files with 45 additions and 18 deletions

View file

@ -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)

View file

@ -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

View file

@ -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"

View file

@ -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 *)