Skip to content

Add some utility functions to Belt Array #4734

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions jscomp/main/builtin_cmi_datasets.ml

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions jscomp/main/builtin_cmj_datasets.ml

Large diffs are not rendered by default.

96 changes: 96 additions & 0 deletions jscomp/others/belt_Array.ml
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ let forEachU a f =

let forEach a f = forEachU a (fun[@bs] a -> f a)

let forEachReverseU a f =
for i = length a - 1 downto 0 do f a.!(i) [@bs] done

let forEachReverse a f = forEachReverseU a (fun[@bs] a -> f a)

let mapU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
Expand All @@ -267,6 +272,17 @@ let mapU a f =

let map a f = mapU a (fun[@bs] a -> f a)

let mapReverseU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
let lastIndex = l - 1 in
for i = 0 to lastIndex do
r.!(i) <- f a.!(lastIndex - i) [@bs]
done;
r

let mapReverse a f = mapReverseU a (fun[@bs] a -> f a)

let getByU a p =
let l = length a in
let i = ref 0 in
Expand Down Expand Up @@ -316,6 +332,23 @@ let keepU a f =

let keep a f = keepU a (fun [@bs] a -> f a)

let keepReverseU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
let j = ref 0 in
for i = l - 1 downto 0 do
let v = a.!(i) in
if f v [@bs] then
begin
r.!(j.contents) <- v;
j.contents <- j.contents + 1
end
done;
truncateToLengthUnsafe r j.contents;
r

let keepReverse a f = keepReverseU a (fun [@bs] a -> f a)

let keepWithIndexU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
Expand All @@ -333,6 +366,23 @@ let keepWithIndexU a f =

let keepWithIndex a f = keepWithIndexU a (fun [@bs] a i -> f a i)

let keepReverseWithIndexU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
let j = ref 0 in
for i = l - 1 downto 0 do
let v = a.!(i) in
if f v i [@bs] then
begin
r.!(j.contents) <- v;
j.contents <- j.contents + 1
end
done;
truncateToLengthUnsafe r j.contents;
r

let keepReverseWithIndex a f = keepReverseWithIndexU a (fun [@bs] a i -> f a i)

let keepMapU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
Expand All @@ -352,11 +402,35 @@ let keepMapU a f =

let keepMap a f = keepMapU a (fun[@bs] a -> f a)

let keepMapReverseU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
let j = ref 0 in
for i = l - 1 downto 0 do
let v = a.!(i) in
match f v [@bs] with
| None -> ()
| Some v ->
begin
r.!(j.contents) <- v;
j.contents <- j.contents + 1
end
done;
truncateToLengthUnsafe r j.contents;
r

let keepMapReverse a f = keepMapReverseU a (fun[@bs] a -> f a)

let forEachWithIndexU a f=
for i = 0 to length a - 1 do f i a.!(i) [@bs] done

let forEachWithIndex a f = forEachWithIndexU a (fun[@bs] a b -> f a b)

let forEachReverseWithIndexU a f=
for i = length a - 1 downto 0 do f i a.!(i) [@bs] done

let forEachReverseWithIndex a f = forEachReverseWithIndexU a (fun[@bs] a b -> f a b)

let mapWithIndexU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
Expand All @@ -367,6 +441,17 @@ let mapWithIndexU a f =

let mapWithIndex a f = mapWithIndexU a (fun[@bs] a b -> f a b)

let mapReverseWithIndexU a f =
let l = length a in
let r = makeUninitializedUnsafe l in
let lastIndex = l - 1 in
for i = 0 to lastIndex do
r.!(i) <- f i a.!(lastIndex - i) [@bs]
done;
r

let mapReverseWithIndex a f = mapReverseWithIndexU a (fun[@bs] a b -> f a b)

let reduceU a x f =
let r = ref x in
for i = 0 to length a - 1 do
Expand Down Expand Up @@ -511,3 +596,14 @@ let unzip a =
a2.!(i) <- v2
done;
(a1, a2)

let joinWithU a sep toString =
match length a with
| 0 -> ""
| l ->
let lastIndex = l - 1 in
let rec aux i res =
if i = lastIndex then res ^ toString a.!(i) [@bs]
else aux (i + 1) (res ^ toString a.!(i) [@bs] ^ sep) in
aux 0 ""
let joinWith a sep toString = joinWithU a sep (fun [@bs] x -> toString x)
145 changes: 137 additions & 8 deletions jscomp/others/belt_Array.mli
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,29 @@ val forEach: 'a array -> ('a -> unit ) -> unit
]}
*)

val forEachReverseU: 'a array -> ('a -> unit [@bs]) -> unit
val forEachReverse: 'a array -> ('a -> unit ) -> unit
(** [forEachReverse xs f]

Call [f] on each element of [xs] from the end to the beginning. [f] returns [unit];so no
new array is created. Use [forEachReverse] when you are primarily concerned with repetitively
creating side effects.

@example {[
forEachReverse [|"a";"b";"c"|] (fun x -> Js.log("Item: " ^ x));;
(* prints:
Item: c
Item: b
Item: a
*)

let total = ref 0;;
forEach [|1;2;3;4|] (fun x -> total := !total + x);;
!total = 4 + 3 + 2 + 1 + 0;;

]}
*)

val mapU: 'a array -> ('a -> 'b [@bs]) -> 'b array
val map: 'a array -> ('a -> 'b ) -> 'b array
(** [map xs f ]
Expand All @@ -365,7 +388,20 @@ val map: 'a array -> ('a -> 'b ) -> 'b array
the beginning to end

@example {[
map [|1;2|] (fun x-> x + 1) = [|3;4|]
map [|1;2|] (fun x-> x + 10) = [|11;12|]
]}

*)

val mapReverseU: 'a array -> ('a -> 'b [@bs]) -> 'b array
val mapReverse: 'a array -> ('a -> 'b ) -> 'b array
(** [mapReverse xs f ]

@return a new array by calling [f] for each element of [xs] from
the end to the beginning

@example {[
mapReverse [|1;2|] (fun x-> x + 10) = [|12;11|]
]}

*)
Expand Down Expand Up @@ -393,48 +429,85 @@ val getIndexBy: 'a array -> ('a -> bool) -> int option
val keepU: 'a array -> ('a -> bool [@bs]) -> 'a array
val keep: 'a array -> ('a -> bool ) -> 'a array
(** [keep xs p ]
@return a new array that keep all elements satisfy [p]
@return a new array that keeps all elements satisfying [p]

@example {[
keep [|1;2;3|] (fun x -> x mod 2 = 0) = [|2|]
]}
*)

val keepReverseU: 'a array -> ('a -> bool [@bs]) -> 'a array
val keepReverse: 'a array -> ('a -> bool ) -> 'a array
(** [keepReverse xs p ]
@return a new array that keeps all elements satisfying [p] from the
last to the first element of [xs].

@example {[
keepReverse [|1;2;3|] (fun x -> x mod 2 = 1) = [|3;1|]
]}
*)

val keepWithIndexU: 'a array -> ('a -> int -> bool [@bs]) -> 'a array
val keepWithIndex: 'a array -> ('a -> int -> bool ) -> 'a array
(** [keepWithIndex xs p ]
@return a new array that keep all elements satisfy [p]
@return a new array that keeps all elements satisfying [p].
The predicate [p] takes two arguments:
the element from [xs] and the index starting from 0.

@example {[
keepWithIndex [|1;2;3|] (fun _x i -> i = 1) = [|2|]
]}
*)

val keepReverseWithIndexU: 'a array -> ('a -> int -> bool [@bs]) -> 'a array
val keepReverseWithIndex: 'a array -> ('a -> int -> bool ) -> 'a array
(** [keepReverseWithIndex xs p ]
@return a new array that keeps all elements satisfying [p] from the
last to the first element of [xs]. The predicate [p] takes two arguments:
the element from [xs] and the index starting from [length - 1] down to 0.

@example {[
keepReverseWithIndex [|1;2;3|] (fun _x i -> i mod 2 = 1) = [|3;1|]
]}
*)

val keepMapU: 'a array -> ('a -> 'b option [@bs]) -> 'b array
val keepMap: 'a array -> ('a -> 'b option) -> 'b array
(** [keepMap xs p]
@return a new array that keep all elements that return a non-None applied [p]
@return a new array that keeps all elements that return a non-None when applied to [p]

@example {[
keepMap [|1;2;3|] (fun x -> if x mod 2 then Some x else None)
keepMap [|1;2;3|] (fun x -> if x mod 2 = 0 then Some x else None)
= [| 2 |]
]}
*)

val keepMapReverseU: 'a array -> ('a -> 'b option [@bs]) -> 'b array
val keepMapReverse: 'a array -> ('a -> 'b option) -> 'b array
(** [keepMapReverse xs p]
@return a new array that keeps all elements that return a non-None when
applied to [p] from the last to the first element of [xs]

@example {[
keepMapReverse [|1;2;3|] (fun x -> if x mod 2 = 1 then Some x else None)
= [|3; 1|]
]}
*)

val forEachWithIndexU: 'a array -> (int -> 'a -> unit [@bs]) -> unit
val forEachWithIndex: 'a array -> (int -> 'a -> unit ) -> unit
(** [forEachWithIndex xs f]

The same as {!forEach};except that [f] is supplied two arguments:
The same as {!forEach}; except that [f] is supplied with two arguments:
the index starting from 0 and the element from [xs]

@example {[

forEach [|"a";"b";"c"|] (fun i x -> Js.log("Item " ^ (string_of_int i) ^ " is " ^ x));;
forEachWithIndex [|"a";"b";"c"|] (fun i x -> Js.log("Item " ^ (string_of_int i) ^ " is " ^ x));;
(* prints:
Item 0 is a
Item 1 is b
Item 2 is cc
Item 2 is c
*)

let total = ref 0 ;;
Expand All @@ -444,6 +517,30 @@ val forEachWithIndex: 'a array -> (int -> 'a -> unit ) -> unit

*)

val forEachReverseWithIndexU: 'a array -> (int -> 'a -> unit [@bs]) -> unit
val forEachReverseWithIndex: 'a array -> (int -> 'a -> unit ) -> unit
(** [forEachReverseWithIndex xs f]

The same as {!forEachReverse}; except that [f] is supplied with two arguments:
the index from [length xs - 1] down to 0 and the element from [xs]

@example {[

forEachReverseWithIndex [|"a";"b";"c"|] (fun i x -> Js.log("Item " ^ (string_of_int i) ^ " is " ^ x));;
(* prints:
Item 2 is c
Item 1 is b
Item 0 is a
*)

let total = ref 0 ;;
forEachReverseWithIndex [|10;11;12;13|] (fun i x -> total := !total + x + i);;
!total = 3 + 13 + 2 + 12 + 1 + 11 + 0 + 10;;
]}

*)


val mapWithIndexU: 'a array -> (int -> 'a -> 'b [@bs]) -> 'b array
val mapWithIndex: 'a array -> (int -> 'a -> 'b ) -> 'b array
(** [mapWithIndex xs f ]
Expand All @@ -457,6 +554,20 @@ val mapWithIndex: 'a array -> (int -> 'a -> 'b ) -> 'b array
]}
*)

val mapReverseWithIndexU: 'a array -> (int -> 'a -> 'b [@bs]) -> 'b array
val mapReverseWithIndex: 'a array -> (int -> 'a -> 'b ) -> 'b array
(** [mapReverseWithIndex xs f ]

[mapReverseWithIndex xs f] applies [f] to each element of [xs]
from the last to the first. Function [f] takes two arguments:
the index starting from [length - 1] down to 0 and the element from [xs].

@example {[
mapReverseWithIndex [|1;2;3|] (fun i x -> i + x) =
[|2 + 3; 1 + 2 ; 0 + 1|]
]}
*)


val partitionU : 'a array -> ('a -> bool [@bs]) -> 'a array * 'a array
val partition : 'a array -> ('a -> bool) -> 'a array * 'a array
Expand Down Expand Up @@ -522,6 +633,24 @@ val reduceWithIndex: 'a array -> 'b -> ('b -> 'a -> int -> 'b) -> 'b
]}
*)

val joinWithU: 'a array -> string -> ('a -> string [@bs]) -> string
val joinWith: 'a array -> string -> ('a -> string) -> string
(** [joinWith xs sep toString]

Concatenates all the elements of [xs] converted to string with [toString], each separated by [sep], the string
given as the second argument, into a single string.
If the array has only one element, then that element will be returned
without using the separator.
If the array is empty, the empty string will be returned.

@example{[
joinWith [|0; 1|] ", " string_of_int = "0, 1"
joinWith [||] " " string_of_int = ""
joinWith [|1|] " " string_of_int = "1"

]}
*)

val someU: 'a array -> ('a -> bool [@bs]) -> bool
val some: 'a array -> ('a -> bool) -> bool
(** [some xs p]
Expand Down
Loading