API / JavaScript / Belt / Array

Array

Utililites for Array functions.

let length: array('a) => int;

return the size of the array

RE
/* Returns 1 */ Belt.Array.length([|"test"|]);
let size: array('a) => int;

See Belt_Array.length

let get: (array('a), int) => option('a);

If i <= 0 <= length(arr) returns Some(value) where value is the item at index i. If i is out of range returns None

let getExn: (array('a), int) => 'a;

Raise an exception if i is out of range. Otherwise return the value at index i in arr.

let getUnsafe: (array('a), int) => 'a;

Unsafe

no bounds checking; this would cause type error if i does not stay within range

let getUndefined: (array('a), int) => Js.undefined('a);

It does the samething in the runtime as Belt_Array.getUnsafe it is type safe since the return type still track whether it is in range or not

let set: (array('a), int, 'a) => bool;

set(arr, n, x); modifies arr in place; it replaces the nth element of arr with x.

Returns false means not updated due to out of range.

let setExn: (array('a), int, 'a) => unit;

setExn(arr, i, x); raise an exception if i is out of range.

let setUnsafe: (array('a), int, 'a) => unit;
let shuffleInPlace: array('a) => unit;

shuffleInPlace(arr) randomly re-orders the items in arr

let shuffle: array('a) => array('a);

Returns a fresh array with items in original array randomly shuffled.

let reverseInPlace: array('a) => unit;

reverseInPlace(arr) reverses items in arr in place.

RE
let arr = [|10, 11, 12, 13, 14|]; let () = Belt.Array.reverseInPlace(arr); arr == [|14, 13, 12, 11, 10|];
let reverse: array('a) => array('a);

reverse(arr) returns a fresh array with items in arr in reverse order.

RE
Belt.Array.reverse([|10, 11, 12, 13, 14|]) == [|14, 13, 12, 11, 10|];
let makeUninitialized: int => array(Js.undefined('a));

makeUninitialized(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.

RE
let arr: array(Js.undefined(string)) = Belt.Array.makeUninitialized(5); Belt.Array.getExn(arr, 0) == Js.undefined;
let makeUninitializedUnsafe: int => array('a);

Unsafe

RE
let arr = Belt.Array.makeUninitializedUnsafe(5); let () = Js.log(Belt.Array.getExn(arr, 0)); /* undefined */ Belt.Array.setExn(arr, 0, "example"); let () = Js.log(Belt.Array.getExn(arr, 0) == "example");
let make: (int, 'a) => array('a);

make(n, e) return an array of size n filled with value e. Returns an empty array when n is negative.

let range: (int, int) => array(int);

range(start, finish); create an inclusive array.

RE
Belt.Array.range(0, 3) == [|0, 1, 2, 3|]; Belt.Array.range(3, 0) == [||]; Belt.Array.range(3, 3) == [|3|];
let rangeBy: (int, int, ~step: int) => array(int);

rangeBy(start, finish, ~step);

Returns empty array when step is 0 or negative. It also return an empty array when start > finish.

RE
Belt.Array.rangeBy(0, 10, ~step=3) == [|0, 3, 6, 9|]; Belt.Array.rangeBy(0, 12, ~step=3) == [|0, 3, 6, 9, 12|]; Belt.Array.rangeBy(33, 0, ~step=1) == [||]; Belt.Array.rangeBy(33, 0, ~step=-1) == [||]; Belt.Array.rangeBy(3, 12, ~step=-1) == [||]; Belt.Array.rangeBy(3, 3, ~step=0) == [||]; Belt.Array.rangeBy(3, 3, ~step=1) == [|3|];
let makeByU: (int, [@bs] (int => 'a)) => array('a);
let makeBy: (int, int => 'a) => array('a);

makeBy(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.

RE
Belt.Array.makeBy(5, (i) => i) == [|0, 1, 2, 3, 4|]; Belt.Array.makeBy(5, (i) => i * i) == [|0, 1, 4, 9, 16|];
let makeByAndShuffleU: (int, [@bs] (int => 'a)) => array('a);
let makeByAndShuffle: (int, int => 'a) => array('a);

makeByAndShuffle(n, f);

Equivalent to shuffle(makeBy(n, f));

let zip: (array('a), array('b)) => array(('a, 'b));

zip(a, b);

Create an array of pairs from corresponding elements of a and b. Stop with the shorter array.

RE
Belt.Array.zip([|1, 2|], [|3, 4, 5|]) == [|(1, 3), (2, 4)|]
let zipByU: (array('a), array('b), [@bs] (('a, 'b) => 'c)) => array('c);
let zipBy: (array('a), array('b), ('a, 'b) => 'c) => array('c);

zipBy(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), ((a, b)) => f(a, b));

RE
Belt.Array.zipBy([|1, 2, 3|], [|4, 5|], (a, b) => 2 * a + b) == [|6, 9|];
let unzip: array(('a, 'b)) => (array('a), array('b));

unzip(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.

RE
Belt.Array.unzip([|(1, 2), (3, 4)|]) == ([|1, 3|], [|2, 4|]); Belt.Array.unzip([|(1, 2), (3, 4), (5, 6), (7, 8)|]) == ([|1, 3, 5, 7|], [|2, 4, 6, 8|]);
let concat: (array('a), array('a)) => array('a);

concat(xs, ys);

Returns a fresh array containing the concatenation of the arrays v1 and v2;so even if v1 or v2 is empty; it can not be shared

RE
Belt.Array.concat([|1, 2, 3|], [|4, 5|]) == [|1, 2, 3, 4, 5|]; Belt.Array.concat([||], [|"a", "b", "c"|]) == [|"a", "b", "c"|];
let concatMany: array(array('a)) => array('a);

concatMany(xss);

Returns a fresh array as the concatenation of xss (an array of arrays)

RE
Belt.Array.concatMany([|[|1, 2, 3|], [|4, 5, 6|], [|7, 8|]|]) == [|1, 2, 3, 4, 5, 6, 7, 8|];
let slice: (array('a), ~offset: int, ~len: int) => array('a);

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.

RE
Belt.Array.slice([|10, 11, 12, 13, 14, 15, 16|], ~offset=2, ~len=3) == [|12, 13, 14|]; Belt.Array.slice([|10, 11, 12, 13, 14, 15, 16|], ~offset=-4, ~len=3) == [|13, 14, 15|]; Belt.Array.slice([|10, 11, 12, 13, 14, 15, 16|], ~offset=4, ~len=9) == [|14, 15, 16|];
let sliceToEnd: (array('a), int) => array('a);

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

RE
Belt.Array.sliceToEnd([|10, 11, 12, 13, 14, 15, 16|], 2) == [|12, 13, 14, 15, 16|]; Belt.Array.sliceToEnd([|10, 11, 12, 13, 14, 15, 16|], -4) == [|13, 14, 15, 16|];
let copy: array('a) => array('a);

copy(a);

Returns a copy of a; that is; a fresh array containing the same elements as a.

let fill: (array('a), ~offset: int, ~len: int, 'a) => unit;

fill(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

RE
let arr = Belt.Array.makeBy(5, (i) => i); Belt.Array.fill(arr, ~offset=2, ~len=2, 9); arr == [|0, 1, 9, 9, 4|]; Belt.Array.fill(arr, ~offset=7, ~len=2, 8); arr == [|0, 1, 9, 9, 4|];
let blit: ( ~src: array('a), ~srcOffset: int, ~dst: array('a), ~dstOffset: int, ~len: int ) => unit;

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.

RE
let v1 = [|10, 11, 12, 13, 14, 15, 16, 17|]; let v2 = [|20, 21, 22, 23, 24, 25, 26, 27|]; Belt.Array.blit(~src=v1, ~srcOffset=4, ~dst=v2, ~dstOffset=2, ~len=3); v2 == [|20, 21, 14, 15, 16, 25, 26, 27|]; Belt.Array.blit(~src=v1, ~srcOffset=4, ~dst=v1, ~dstOffset=2, ~len=3); v1 == [|10, 11, 14, 15, 16, 15, 16, 17|];
let blitUnsafe: (~src: array('a), ~srcOffset: int, ~dst: array('a), ~dstOffset: int, ~len: int) => unit;

Unsafe blit without bounds checking.

let forEachU: (array('a), [@bs] ('a => unit)) => unit;
let forEach: (array('a), 'a => unit) => unit;

forEach(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.

RE
Belt.Array.forEach([|"a", "b", "c"|], x => Js.log("Item: " ++ x)); /* prints: Item: a Item: b Item: c */ let total = ref(0); Belt.Array.forEach([|1, 2, 3, 4|], x => total := total^ + x); total^ == 1 + 2 + 3 + 4;
let mapU: (array('a), [@bs] ('a => 'b)) => array('b);
let map: (array('a), 'a => 'b) => array('b);

map(xs, f);

Returns a new array by calling f for each element of xs from the beginning to end.

RE
Belt.Array.map([|1, 2|], (x) => x + 1) == [|3, 4|];
let getByU: (array('a), [@bs] ('a => bool)) => option('a);
let getBy: (array('a), 'a => bool) => option('a);

getBy(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.

RE
Belt.Array.getBy([|1, 4, 3, 2|], (x) => x mod 2 == 0) == Some(4); Belt.Array.getBy([|15, 13, 11|], (x) => x mod 2 == 0) == None;
let getIndexByU: (array('a), [@bs] ('a => bool)) => option(int);
let getIndexBy: (array('a), 'a => bool) => option(int);

getIndexBy(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.

RE
Belt.Array.getIndexBy([|1, 4, 3, 2|], (x) => x mod 2 == 0) == Some(1); Belt.Array.getIndexBy([|15, 13, 11|], (x) => x mod 2 == 0) == None;
let keepU: (array('a), [@bs] ('a => bool)) => array('a);
let keep: (array('a), 'a => bool) => array('a);

keep(xs, p);

Returns a new array that keep all elements satisfy p.

RE
Belt.Array.keep([|1, 2, 3|], (x) => x mod 2 == 0) == [|2|];
let keepWithIndexU: (array('a), [@bs] (('a, int) => bool)) => array('a);
let keepWithIndex: (array('a), ('a, int) => bool) => array('a);

keepWithIndex(xs, p);

Returns a new array that keep all elements satisfy p.

RE
Belt.Array.keepWithIndex([|1, 2, 3|], (_x, i) => i == 1) == [|2|];
let keepMapU: (array('a), [@bs] ('a => option('b))) => array('b);
let keepMap: (array('a), 'a => option('b)) => array('b);

keepMap(xs, p);

Returns a new array that keep all elements that return a non-None applied p.

RE
Belt.Array.keepMap([|1, 2, 3|], x => if (x mod 2 == 0) { Some(x); } else { None; } ) == [|2|];
let forEachWithIndexU: (array('a), [@bs] ((int, 'a) => unit)) => unit;
let forEachWithIndex: (array('a), (int, 'a) => unit) => unit;

forEachWithIndex(xs, f);

The same as Belt_Array.forEach; except that f is supplied two arguments: the index starting from 0 and the element from xs.

RE
Belt.Array.forEachWithIndex([|"a", "b", "c"|], (i, x) => Js.log("Item " ++ string_of_int(i) ++ " is " ++ x)); /* prints: Item 0 is a Item 1 is b Item 2 is cc */ let total = ref(0); Belt.Array.forEachWithIndex([|10, 11, 12, 13|], (i, x) => total := total^ + x + i); total^ == 0 + 10 + 1 + 11 + 2 + 12 + 3 + 13;
let mapWithIndexU: (array('a), [@bs] ((int, 'a) => 'b)) => array('b);
let mapWithIndex: (array('a), (int, 'a) => 'b) => array('b);

mapWithIndex(xs, f);

mapWithIndex(xs, f) applies f to each element of xs. Function f takes two arguments: the index starting from 0 and the element from xs.

RE
Belt.Array.mapWithIndex([|1, 2, 3|], (i, x) => i + x) == [|0 + 1, 1 + 2, 2 + 3|];
let partitionU: (array('a), [@bs] ('a => bool)) => (array('a), array('a));
let partition: (array('a), 'a => bool) => (array('a), array('a));

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

RE
Belt.Array.partition([|1, 2, 3, 4, 5|], (x) => x mod 2 == 0) == ([|2, 4|], [|1, 2, 3|]); Belt.Array.partition([|1, 2, 3, 4, 5|], (x) => x mod 2 != 0) == ([|1, 2, 3|], [|2, 4|]);
let reduceU: (array('b), 'a, [@bs] (('a, 'b) => 'a)) => 'a;
let reduce: (array('b), 'a, ('a, 'b) => 'a) => 'a;

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.

RE
Belt.Array.reduce([|2, 3, 4|], 1, (+)) == 10; Belt.Array.reduce([|"a", "b", "c", "d"|], "", (++)) == "abcd";
let reduceReverseU: (array('b), 'a, [@bs] (('a, 'b) => 'a)) => 'a;
let reduceReverse: (array('b), 'a, ('a, 'b) => 'a) => 'a;

reduceReverse(xs, init, f);

Works like Belt_Array.reduce; except that function f is applied to each item of xs from the last back to the first.

RE
Belt.Array.reduceReverse([|"a", "b", "c", "d"|], "", (++)) == "dcba";
let reduceReverse2U: (array('a), array('b), 'c, [@bs] (('c, 'a, 'b) => 'c)) => 'c;
let reduceReverse2: (array('a), array('b), 'c, ('c, 'a, 'b) => 'c) => 'c;

reduceReverse2(xs, ys, init, f);

Reduces two arrays xs and ys;taking items starting at min(length(xs), length(ys)) down to and including zero.

RE
Belt.Array.reduceReverse2([|1, 2, 3|], [|1, 2|], 0, (acc, x, y) => acc + x + y) == 6;
let reduceWithIndexU: (array('a), 'b, [@bs] (('b, 'a, int) => 'b)) => 'b;
let reduceWithIndex: (array('a), 'b, ('b, 'a, int) => 'b) => 'b;

reduceWithIndex(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.

RE
Belt.Array.reduceWithIndex([|1, 2, 3, 4|], 0, (acc, x, i) => acc + x + i) == 16;
let someU: (array('a), [@bs] ('a => bool)) => bool;
let some: (array('a), 'a => bool) => bool;

some(xs, p);

Returns true if at least one of the elements in xs satifies p; where p is a predicate: a function taking an element and returning a bool.

RE
Belt.Array.some([|2, 3, 4|], (x) => x mod 2 == 1) == true; Belt.Array.some([|(-1), (-3), (-5)|], (x) => x > 0) == false;
let everyU: (array('a), [@bs] ('a => bool)) => bool;
let every: (array('a), 'a => bool) => bool;

every(xs, p);

Returns true if all elements satisfy p; where p is a predicate: a function taking an element and returning a bool.

RE
Belt.Array.every([|1, 3, 5|], (x) => x mod 2 == 1) == true; Belt.Array.every([|1, (-3), 5|], (x) => x > 0) == false;
let every2U: (array('a), array('b), [@bs] (('a, 'b) => bool)) => bool;
let every2: (array('a), array('b), ('a, 'b) => bool) => bool;

every2(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));)

RE
Belt.Array.every2([|1, 2, 3|], [|0, 1|], (>)) == true; Belt.Array.every2([||], [|1|], (x, y) => x > y) == true; Belt.Array.every2([|2, 3|], [|1|], (x, y) => x > y) == true; Belt.Array.every2([|0, 1|], [|5, 0|], (x, y) => x > y) == false;
let some2U: (array('a), array('b), [@bs] (('a, 'b) => bool)) => bool;
let some2: (array('a), array('b), ('a, 'b) => bool) => bool;

some2(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));)

RE
Belt.Array.some2([|0, 2|], [|1, 0, 3|], (>)) == true; Belt.Array.some2([||], [|1|], (x, y) => x > y) == false; Belt.Array.some2([|2, 3|], [|1, 4|], (x, y) => x > y) == true;
let cmpU: (array('a), array('a), [@bs] (('a, 'a) => int)) => int;
let cmp: (array('a), array('a), ('a, 'a) => int) => int;

cmp(xs, ys, f);

Compared by length if length(xs) != length(ys); returning -1 if length(xs) < length(ys) or 1 if length(xs) > length(ys) Otherwise compare one by one f(x, y);. f returns a negative number if x is “less than” y zero if x is “equal to” y a positive number if x is “greater than” y The comparison returns the first non-zero result of f;or zero if f returns zero for all x and y.

RE
Belt.Array.cmp([|1, 3, 5|], [|1, 4, 2|], (a, b) => compare(a, b)) == (-1); Belt.Array.cmp([|1, 3, 5|], [|1, 2, 3|], (a, b) => compare(a, b)) == 1; Belt.Array.cmp([|1, 3, 5|], [|1, 3, 5|], (a, b) => compare(a, b)) == 0;
let eqU: (array('a), array('a), [@bs] (('a, 'a) => bool)) => bool;
let eq: (array('a), array('a), ('a, 'a) => bool) => bool;

eq(xs, ys);

return false if length is not the same otherwise compare items one by one using f(xi, yi);; and return true if all results are true;false otherwise

RE
Belt.Array.eq([|1, 2, 3|], [|(-1), (-2), (-3)|], (a, b) => abs(a) == abs(b)) == true;
let truncateToLengthUnsafe: (array('a), int) => unit;

Unsafe truncateToLengthUnsafe(xs, n); sets length of array xs to n.

If n is greater than the length of xs; the extra elements are set to Js.Null_undefined.null.

If n is less than zero; raises a RangeError.

RE
let arr = [|"ant", "bee", "cat", "dog", "elk"|]; Belt.Array.truncateToLengthUnsafe(arr, 3); arr == [|"ant", "bee", "cat"|];