mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
fold_while impl for CCList and CCArray
This commit is contained in:
parent
e1d25d6da7
commit
397f60e6ac
4 changed files with 53 additions and 3 deletions
|
|
@ -53,6 +53,11 @@ module type S = sig
|
|||
val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b
|
||||
(** fold left on array, with index *)
|
||||
|
||||
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a
|
||||
(** fold left on array until a stop condition via [('a, `Stop)] is
|
||||
indicated by the accumulator
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val iter : ('a -> unit) -> 'a t -> unit
|
||||
|
||||
val iteri : (int -> 'a -> unit) -> 'a t -> unit
|
||||
|
|
@ -276,6 +281,20 @@ let fold = Array.fold_left
|
|||
|
||||
let foldi f acc a = _foldi f acc a 0 (Array.length a)
|
||||
|
||||
let fold_while f acc a =
|
||||
let rec fold_while_i f acc i =
|
||||
if i < Array.length a then
|
||||
let acc, cont = f acc a.(i) in
|
||||
match cont with
|
||||
| `Stop -> acc
|
||||
| `Continue -> fold_while_i f acc (i+1)
|
||||
else acc
|
||||
in fold_while_i f acc 0
|
||||
|
||||
(*$T
|
||||
fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 (Array.of_list [true;true;false;true]) = 2
|
||||
*)
|
||||
|
||||
let iter = Array.iter
|
||||
|
||||
let iteri = Array.iteri
|
||||
|
|
@ -480,6 +499,16 @@ module Sub = struct
|
|||
|
||||
let foldi f acc a = _foldi f acc a.arr a.i a.j
|
||||
|
||||
let fold_while f acc a =
|
||||
let rec fold_while_i f acc i =
|
||||
if i < Array.length a.arr && i < a.j then
|
||||
let acc, cont = f acc a.arr.(i) in
|
||||
match cont with
|
||||
| `Stop -> acc
|
||||
| `Continue -> fold_while_i f acc (i+1)
|
||||
else acc
|
||||
in fold_while_i f acc a.i
|
||||
|
||||
let get a i =
|
||||
let j = a.i + i in
|
||||
if i<0 || j>=a.j then invalid_arg "Array.Sub.get";
|
||||
|
|
|
|||
|
|
@ -50,10 +50,15 @@ module type S = sig
|
|||
|
||||
val length : _ t -> int
|
||||
|
||||
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
|
||||
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||
|
||||
val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b
|
||||
(** fold left on array, with index *)
|
||||
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||
(** Fold left on array, with index *)
|
||||
|
||||
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a
|
||||
(** Fold left on array until a stop condition via [('a, `Stop)] is
|
||||
indicated by the accumulator
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val iter : ('a -> unit) -> 'a t -> unit
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,17 @@ let fold_right f l acc =
|
|||
l = fold_right (fun x y->x::y) l [])
|
||||
*)
|
||||
|
||||
let rec fold_while f acc = function
|
||||
| [] -> acc
|
||||
| e::l -> let acc, cont = f acc e in
|
||||
match cont with
|
||||
| `Stop -> acc
|
||||
| `Continue -> fold_while f acc l
|
||||
|
||||
(*$T
|
||||
fold_while (fun acc b -> if b then acc+1, `Continue else acc, `Stop) 0 [true;true;false;true] = 2
|
||||
*)
|
||||
|
||||
let init len f =
|
||||
let rec init_rec acc i f =
|
||||
if i=0 then f i :: acc
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ val filter : ('a -> bool) -> 'a t -> 'a t
|
|||
val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b
|
||||
(** Safe version of [fold_right] *)
|
||||
|
||||
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a
|
||||
(** Fold until a stop condition via [('a, `Stop)] is
|
||||
indicated by the accumulator
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val init : int -> (int -> 'a) -> 'a t
|
||||
(** Same as [Array.init]
|
||||
@since 0.6 *)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue