Belt.Arraymutable array: Utilities functions
Belt.Array Utililites for Array functions
val length : 'a t -> intlength xs return the size of the array
val get : 'a t -> int -> 'a optionget arr i
If i <= 0 <= length arr;returns Some value where value is the item at index i If i is out of range;returns None
Belt.Array.get [| "a"; "b"; "c" |] 0 = Some "a";;
Belt.Array.get [| "a"; "b"; "c" |] 3 = None;;
Belt.Array.get [| "a"; "b"; "c" |] (-1) = Noneval getExn : 'a t -> int -> 'agetExn arr i
raise an exception if i is out of range;otherwise return the value at index i in arr
val getUnsafe : 'a t -> int -> 'agetUnsafe arr i
Unsafe
no bounds checking;this would cause type error if i does not stay within range
val getUndefined : 'a t -> int -> 'a Js.undefinedgetUndefined arr i
It does the same thing in the runtime as getUnsafe; it is type safe since the return type still tracks whether it is in range or not. On native this is represented using the same option-backed encoding as Js.Undefined.
val set : 'a t -> int -> 'a -> boolset arr n x modifies arr in place; it replaces the nth element of arr with x
val setExn : 'a t -> int -> 'a -> unitsetExn arr i x raise an exception if i is out of range
val setUnsafe : 'a t -> int -> 'a -> unitval shuffleInPlace : 'a t -> unitshuffleInPlace arr randomly re-orders the items in arr
val reverseInPlace : 'a t -> unitreverseInPlace arr reverses items in arr in place
let arr = [| 10; 11; 12; 13; 14 |]
let () = reverseInPlace arr;;
arr = [| 14; 13; 12; 11; 10 |]val makeUninitialized : int -> 'a Js.undefined arraymakeUninitialized n creates an array of length n filled with the undefined value. You must specify the type of data that will eventually fill the array.
let arr : string Js.undefined array = makeUninitialized 5;;
getExn arr 0 = Js.undefinedmakeUninitializedUnsafe n filler
Unsafe
Native approximation of the JavaScript makeUninitializedUnsafe. Since OCaml arrays must be fully initialized, the filler value is used to allocate the array before callers overwrite the slots they need. Unread slots therefore contain filler, not JavaScript-style holes or undefined.
let arr = Belt.Array.makeUninitializedUnsafe 5 "placeholder";;
Belt.Array.setExn arr 0 "example";;
Belt.Array.getExn arr 0 = "example"val make : int -> 'a -> 'a tmake n e return an array of size n filled with value e
val range : int -> int -> int trange start finish create an inclusive array
range 0 3 = [| 0; 1; 2; 3 |];;
range 3 0 = [||];;
range 3 3 = [| 3 |]val rangeBy : int -> int -> step:int -> int trangeBy start finish ~step
rangeBy 0 10 ~step:3 = [| 0; 3; 6; 9 |];;
rangeBy 0 12 ~step:3 = [| 0; 3; 6; 9; 12 |];;
rangeBy 33 0 ~step:1 = [||];;
rangeBy 33 0 ~step:(-1) = [||];;
rangeBy 3 12 ~step:(-1) = [||];;
rangeBy 3 3 ~step:0 = [||];;
rangeBy 3 3 ~step:1 = [| 3 |]val makeByU : int -> (int -> 'a) -> 'a tval makeBy : int -> (int -> 'a) -> 'a tmakeBy n f
return an empty array when n is negative return an array of size n populated by f i start from 0 to n - 1
makeBy 5 (fun i -> i) = [| 0; 1; 2; 3; 4 |];;
makeBy 5 (fun i -> i * i) = [| 0; 1; 4; 9; 16 |]val makeByAndShuffleU : int -> (int -> 'a) -> 'a tval makeByAndShuffle : int -> (int -> 'a) -> 'a tmakeByAndShuffle n f
Equivalent to shuffle (makeBy n f)
val zip : 'a t -> 'b array -> ('a * 'b) arrayzip a b
Create an array of pairs from corresponding elements of a and b. Stop with the shorter array
zip [| 1; 2 |] [| 3; 4; 5 |] = [| (1, 3); (2, 4) |]val zipByU : 'a t -> 'b array -> ('a -> 'b -> 'c) -> 'c arrayval zipBy : 'a t -> 'b array -> ('a -> 'b -> 'c) -> 'c arrayzipBy xs ys f
Create an array by applying f to corresponding elements of xs and ys Stops with shorter array
Equivalent to map (zip xs ys) (fun (a,b) -> f a b)
zipBy [| 1; 2; 3 |] [| 4; 5 |] (fun a b -> (2 * a) + b) = [| 6; 9 |]val unzip : ('a * 'b) array -> 'a t * 'b arrayunzip a takes an array of pairs and creates a pair of arrays. The first array contains all the first items of the pairs; the second array contains all the second items.
unzip [| (1, 2); (3, 4) |] = ([| 1; 3 |], [| 2; 4 |]);;
unzip [| (1, 2); (3, 4); (5, 6); (7, 8) |] = ([| 1; 3; 5; 7 |], [| 2; 4; 6; 8 |])concat xs ys
concat [| 1; 2; 3 |] [| 4; 5 |] = [| 1; 2; 3; 4; 5 |];;
concat [||] [| "a"; "b"; "c" |] = [| "a"; "b"; "c" |]concatMany xss
concatMany [| [| 1; 2; 3 |]; [| 4; 5; 6 |]; [| 7; 8 |] |] = [| 1; 2; 3; 4; 5; 6; 7; 8 |]slice xs offset len creates a new array with the len elements of xs starting at offset for
offset can be negative;and is evaluated as length xs - offset slice xs -1 1 means get the last element as a singleton array
slice xs (-len) len will return a copy of the array
if the array does not have enough data;slice extracts through the end of sequence.
if len is negative;returns the empty array.
slice [| 10; 11; 12; 13; 14; 15; 16 |] ~offset:2 ~len:3 = [| 12; 13; 14 |];;
slice [| 10; 11; 12; 13; 14; 15; 16 |] ~offset:(-4) ~len:3 = [| 13; 14; 15 |];;
slice [| 10; 11; 12; 13; 14; 15; 16 |] ~offset:4 ~len:9 = [| 14; 15; 16 |]sliceToEnd xs offset creates a new array with the elements of xs starting at offset
offset can be negative;and is evaluated as length xs - offset sliceToEnd xs -1 means get the last element as a singleton array
sliceToEnd xs 0 will return a copy of the array
sliceToEnd [| 10; 11; 12; 13; 14; 15; 16 |] 2 = [| 12; 13; 14; 15; 16 |];;
sliceToEnd [| 10; 11; 12; 13; 14; 15; 16 |] (-4) = [| 13; 14; 15; 16 |]val fill : 'a t -> offset:int -> len:int -> 'a -> unitfill arr ~offset ~len x
Modifies arr in place, storing x in elements number offset to offset + len - 1.
offset can be negative;and is evaluated as length arr - offset
fill arr ~offset:(-1) ~len:1 means fill the last element, if the array does not have enough data;fill will ignore it
let arr = makeBy 5 (fun i -> i);;
fill arr ~offset:2 ~len:2 9;;
arr = [| 0; 1; 9; 9; 4 |];;
fill arr ~offset:7 ~len:2 8;;
arr = [| 0; 1; 9; 9; 4 |]blit ~src:v1 ~srcOffset:o1 ~dst:v2 ~dstOffset:o2 ~len
copies len elements from array v1;starting at element number o1;to array v2, starting at element number o2.
It works correctly even if v1 and v2 are the same array;and the source and destination chunks overlap.
offset can be negative;-1 means len - 1;if len + offset is still negative;it will be set as 0
For each of the examples;presume that v1 = [|10;11;12;13;14;15;16;17|] and v2 = [|20;21;22;23;24;25;26;27|]. The result shown is the content of the destination array.
Belt.Array.blit ~src:v1 ~srcOffset:4 ~dst:v2 ~dstOffset:2 ~len:3
|. [| 20; 21; 14; 15; 16; 25; 26; 27 |] Belt.Array.blit ~src:v1 ~srcOffset:4 ~dst:v1 ~dstOffset:2 ~len:3
|. [| 10; 11; 14; 15; 16; 15; 16; 17 |]Unsafe blit without bounds checking
val forEachU : 'a t -> ('a -> unit) -> unitval forEach : 'a t -> ('a -> unit) -> unitforEach xs f
Call f on each element of xs from the beginning to end. f returns unit;so no new array is created. Use forEach when you are primarily concerned with repetitively creating side effects.
forEach [| "a"; "b"; "c" |] (fun x -> Js.log ("Item: " ^ x));;
(* prints:
Item: a
Item: b
Item: c
*)
let total = ref 0;;
forEach [| 1; 2; 3; 4 |] (fun x -> total := !total + x);;
!total = 1 + 2 + 3 + 4val mapU : 'a t -> ('a -> 'b) -> 'b arrayval map : 'a t -> ('a -> 'b) -> 'b arraymap xs f
map [| 1; 2 |] (fun x -> x + 10) = [| 11; 12 |]flatMap xs f **return** a new array by calling `f` for each element of `xs` from the beginning to end, and then concatenating the results ``` flatMap |1;2| (fun x-> |x + 10;x + 20|) = |11;21;12;22| ```
val getByU : 'a t -> ('a -> bool) -> 'a optionval getBy : 'a t -> ('a -> bool) -> 'a optiongetBy xs p returns Some value for the first value in xs that satisifies the predicate function p; returns None if no element satisifies the function.
getBy [|1;4;3;2|] (fun x -> x mod 2 = 0) = Some 4
getBy [|15;13;11|] (fun x -> x mod 2 = 0) = Noneval getIndexByU : 'a t -> ('a -> bool) -> int optionval getIndexBy : 'a t -> ('a -> bool) -> int optiongetIndexBy xs p returns Some index for the first value in xs that satisifies the predicate function p; returns None if no element satisifies the function.
getIndexBy [|1;4;3;2|] (fun x -> x mod 2 = 0) = Some 1
getIndexBy [|15;13;11|] (fun x -> x mod 2 = 0) = Nonekeep xs p
keep [| 1; 2; 3 |] (fun x -> x mod 2 = 0) = [| 2 |]keepWithIndex xs p
keepWithIndex [| 1; 2; 3 |] (fun _x i -> i = 1) = [| 2 |]val keepMapU : 'a t -> ('a -> 'b option) -> 'b arrayval keepMap : 'a t -> ('a -> 'b option) -> 'b arraykeepMap xs p
keepMap [| 1; 2; 3 |] (fun x -> if x mod 2 = 0 then Some x else None) = [| 2 |]val forEachWithIndexU : 'a t -> (int -> 'a -> unit) -> unitval forEachWithIndex : 'a t -> (int -> 'a -> unit) -> unitforEachWithIndex xs f
The same as forEach; except that f is supplied with two arguments: the index starting from 0 and the element from xs
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 c
*)
let total = ref 0;;
forEachWithIndex [| 10; 11; 12; 13 |] (fun i x -> total := !total + x + i);;
!total = 0 + 10 + 1 + 11 + 2 + 12 + 3 + 13mapWithIndex xs f applies f to each element of xs. Function f takes two arguments: the index starting from 0 and the element from xs.
mapWithIndex [| 1; 2; 3 |] (fun i x -> i + x) = [| 0 + 1; 1 + 2; 2 + 3 |]partition f a split array into tuple of two arrays based on predicate f; first of tuple where predicate cause true, second where predicate cause false
partition [| 1; 2; 3; 4; 5 |] (fun x -> x mod 2 = 0) = ([| 2; 4 |], [| 1; 2; 3 |]);;
partition [| 1; 2; 3; 4; 5 |] (fun x -> x mod 2 <> 0) = ([| 1; 2; 3 |], [| 2; 4 |])reduce xs init f
Applies f to each element of xs from beginning to end. Function f has two parameters: the item from the list and an “accumulator”;which starts with a value of init. reduce returns the final value of the accumulator.
reduce [| 2; 3; 4 |] 1 ( + ) = 10;;
reduce [| "a"; "b"; "c"; "d" |] "" ( ^ ) = "abcd"reduceReverse xs init f
Works like reduce;except that function f is applied to each item of xs from the last back to the first.
reduceReverse [| "a"; "b"; "c"; "d" |] "" ( ^ ) = "dcba"val reduceReverse2U : 'a t -> 'b array -> 'c -> ('c -> 'a -> 'b -> 'c) -> 'cval reduceReverse2 : 'a t -> 'b array -> 'c -> ('c -> 'a -> 'b -> 'c) -> 'creduceReverse2 xs ys init f Reduces two arrays xs and ys;taking items starting at min (length xs) (length ys) down to and including zero.
reduceReverse2 [| 1; 2; 3 |] [| 1; 2 |] 0 (fun acc x y -> acc + x + y) = 6val reduceWithIndexU : 'a t -> 'b -> ('b -> 'a -> int -> 'b) -> 'bval reduceWithIndex : 'a t -> 'b -> ('b -> 'a -> int -> 'b) -> 'breduceWithIndex xs f
Applies f to each element of xs from beginning to end. Function f has three parameters: the item from the array and an “accumulator”, which starts with a value of init and the index of each element. reduceWithIndex returns the final value of the accumulator.
reduceWithIndex [| 1; 2; 3; 4 |] 0 (fun acc x i -> acc + x + i) = 16val joinWithU : 'a t -> string -> ('a -> string) -> stringval joinWith : 'a t -> string -> ('a -> string) -> stringjoinWith 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.
joinWith [| 0; 1 |] ", " string_of_int
= "0, 1" joinWith [||] " " string_of_int
= "" joinWith [| 1 |] " " string_of_int = "1"val someU : 'a t -> ('a -> bool) -> boolval some : 'a t -> ('a -> bool) -> boolsome xs p
some [| 2; 3; 4 |] (fun x -> x mod 2 = 1) = true;;
some [| -1; -3; -5 |] (fun x -> x > 0) = falseval everyU : 'a t -> ('a -> bool) -> boolval every : 'a t -> ('a -> bool) -> boolevery xs p
every [| 1; 3; 5 |] (fun x -> x mod 2 = 1) = true;;
every [| 1; -3; 5 |] (fun x -> x > 0) = falseevery2 xs ys p returns true if p xi yi is true for all pairs of elements up to the shorter length (i.e. min (length xs) (length ys))
every2 [| 1; 2; 3 |] [| 0; 1 |] ( > ) = true;;
every2 [||] [| 1 |] (fun x y -> x > y) = true;;
every2 [| 2; 3 |] [| 1 |] (fun x y -> x > y) = true;;
every2 [| 0; 1 |] [| 5; 0 |] (fun x y -> x > y) = falsesome2 xs ys p returns true if p xi yi is true for any pair of elements up to the shorter length (i.e. min (length xs) (length ys))
some2 [| 0; 2 |] [| 1; 0; 3 |] ( > ) = true;;
some2 [||] [| 1 |] (fun x y -> x > y) = false;;
some2 [| 2; 3 |] [| 1; 4 |] (fun x y -> x > y) = truecmp xs ys f
length xs <> length ys;returning -1 iflength xs < length ys or 1 if length xs > length ysf x y. f returnsx is “less than” yx is “equal to” yx is “greater than” yf;or zero if f returns zero for all x and y. cmp [| 1; 3; 5 |] [| 1; 4; 2 |] (fun a b -> compare a b) = -1;;
cmp [| 1; 3; 5 |] [| 1; 2; 3 |] (fun a b -> compare a b) = 1;;
cmp [| 1; 3; 5 |] [| 1; 3; 5 |] (fun a b -> compare a b) = 0eq xs ys
f xi yi;and return true if all results are true;false otherwise eq [| 1; 2; 3 |] [| -1; -2; -3 |] (fun a b -> abs a = abs b) = trueUnsafe Native-only approximation of the JavaScript truncateToLengthUnsafe.
On native this returns a fresh truncated copy of xs. It does not mutate the input array length, and it cannot grow the array because OCaml arrays are fixed length.
Raises Invalid_argument if n is negative or larger than length xs.
let arr = [| "ant"; "bee"; "cat"; "dog"; "elk" |]
let truncated = truncateToLengthUnsafe arr 3;;
truncated = [| "ant"; "bee"; "cat" |];;
arr = [| "ant"; "bee"; "cat"; "dog"; "elk" |]val initU : int -> (int -> 'a) -> 'a tval init : int -> (int -> 'a) -> 'a tval push : 'a t -> 'a -> unitOCaml arrays are fixed length and cannot grow in place like JavaScript arrays: raises at runtime. Use a copy-based helper instead when you need to append on native.