Module Garter_Array

include module type of Belt_Array;
let length: array('a) => int;
let size: array('a) => int;
let get: array('a) => int => option('a);
let getExn: array('a) => int => 'a;
let getUnsafe: array('a) => int => 'a;
let getUndefined: array('a) => int => Js.undefined('a);
let set: array('a) => int => 'a => bool;
let setExn: array('a) => int => 'a => unit;
let setUnsafe: array('a) => int => 'a => unit;
let shuffleInPlace: array('a) => unit;
let shuffle: array('a) => array('a);
let reverseInPlace: array('a) => unit;
let reverse: array('a) => array('a);
let makeUninitialized: int => array(Js.undefined('a));
let makeUninitializedUnsafe: int => array('a);
let make: int => 'a => array('a);
let range: int => int => array(int);
let rangeBy: int => int => step:int => array(int);
let makeByU: int => Js.Fn.arity1((int => 'a)) => array('a);
let makeBy: int => (int => 'a) => array('a);
let makeByAndShuffleU: int => Js.Fn.arity1((int => 'a)) => array('a);
let makeByAndShuffle: int => (int => 'a) => array('a);
let zip: array('a) => array('b) => array(('a, 'b));
let zipByU: array('a) => array('b) => Js.Fn.arity2(('a => 'b => 'c)) => array('c);
let zipBy: array('a) => array('b) => ('a => 'b => 'c) => array('c);
let unzip: array(('a, 'b)) => (array('a), array('b));
let concat: array('a) => array('a) => array('a);
let concatMany: array(array('a)) => array('a);
let slice: array('a) => offset:int => len:int => array('a);
let sliceToEnd: array('a) => int => array('a);
let copy: array('a) => array('a);
let fill: array('a) => offset:int => len:int => 'a => unit;
let blit: src:array('a) => srcOffset:int => dst:array('a) => dstOffset:int => len:int => unit;
let blitUnsafe: src:array('a) => srcOffset:int => dst:array('a) => dstOffset:int => len:int => unit;
let forEachU: array('a) => Js.Fn.arity1(('a => unit)) => unit;
let forEach: array('a) => ('a => unit) => unit;
let mapU: array('a) => Js.Fn.arity1(('a => 'b)) => array('b);
let map: array('a) => ('a => 'b) => array('b);
let getByU: array('a) => Js.Fn.arity1(('a => bool)) => option('a);
let getBy: array('a) => ('a => bool) => option('a);
let getIndexByU: array('a) => Js.Fn.arity1(('a => bool)) => option(int);
let getIndexBy: array('a) => ('a => bool) => option(int);
let keepU: array('a) => Js.Fn.arity1(('a => bool)) => array('a);
let keep: array('a) => ('a => bool) => array('a);
let keepWithIndexU: array('a) => Js.Fn.arity2(('a => int => bool)) => array('a);
let keepWithIndex: array('a) => ('a => int => bool) => array('a);
let keepMapU: array('a) => Js.Fn.arity1(('a => option('b))) => array('b);
let keepMap: array('a) => ('a => option('b)) => array('b);
let forEachWithIndexU: array('a) => Js.Fn.arity2((int => 'a => unit)) => unit;
let forEachWithIndex: array('a) => (int => 'a => unit) => unit;
let mapWithIndexU: array('a) => Js.Fn.arity2((int => 'a => 'b)) => array('b);
let mapWithIndex: array('a) => (int => 'a => 'b) => array('b);
let partitionU: array('a) => Js.Fn.arity1(('a => bool)) => (array('a), array('a));
let partition: array('a) => ('a => bool) => (array('a), array('a));
let reduceU: array('b) => 'a => Js.Fn.arity2(('a => 'b => 'a)) => 'a;
let reduce: array('b) => 'a => ('a => 'b => 'a) => 'a;
let reduceReverseU: array('b) => 'a => Js.Fn.arity2(('a => 'b => 'a)) => 'a;
let reduceReverse: array('b) => 'a => ('a => 'b => 'a) => 'a;
let reduceReverse2U: array('a) => array('b) => 'c => Js.Fn.arity3(('c => 'a => 'b => 'c)) => 'c;
let reduceReverse2: array('a) => array('b) => 'c => ('c => 'a => 'b => 'c) => 'c;
let reduceWithIndexU: array('a) => 'b => Js.Fn.arity3(('b => 'a => int => 'b)) => 'b;
let reduceWithIndex: array('a) => 'b => ('b => 'a => int => 'b) => 'b;
let joinWithU: array('a) => string => Js.Fn.arity1(('a => string)) => string;
let joinWith: array('a) => string => ('a => string) => string;
let someU: array('a) => Js.Fn.arity1(('a => bool)) => bool;
let some: array('a) => ('a => bool) => bool;
let everyU: array('a) => Js.Fn.arity1(('a => bool)) => bool;
let every: array('a) => ('a => bool) => bool;
let every2U: array('a) => array('b) => Js.Fn.arity2(('a => 'b => bool)) => bool;
let every2: array('a) => array('b) => ('a => 'b => bool) => bool;
let some2U: array('a) => array('b) => Js.Fn.arity2(('a => 'b => bool)) => bool;
let some2: array('a) => array('b) => ('a => 'b => bool) => bool;
let cmpU: array('a) => array('a) => Js.Fn.arity2(('a => 'a => int)) => int;
let cmp: array('a) => array('a) => ('a => 'a => int) => int;
let eqU: array('a) => array('a) => Js.Fn.arity2(('a => 'a => bool)) => bool;
let eq: array('a) => array('a) => ('a => 'a => bool) => bool;
let truncateToLengthUnsafe: array('a) => int => unit;
let isEmpty: array('a) => bool;
let firstUnsafe: array('a) => 'a;
let firstExn: array('a) => 'a;
let first: array('a) => option('a);
let lastUnsafe: array('a) => 'a;
let lastExn: array('a) => 'a;
let last: array('a) => option('a);
let take: Js.Array2.t('a) => int => Js.Array2.t('a);

0번째 인덱스부터 최대 n개의 원소를 반환합니다. n이 음수라면 빈 배열을 반환합니다.

let takeWhileU: Js.Array2.t('a) => Js.Fn.arity1(('a => bool)) => Js.Array2.t('a);
let takeWhile: Js.Array2.t('a) => ('a => bool) => Js.Array2.t('a);
let drop: Js.Array2.t('a) => int => Js.Array2.t('a);

0번째 인덱스부터 n개를 제외한 원소들의 배열을 반환합니다. n이 배열의 크기보다 크면 빈 배열 반환합니다.

let dropWhileU: Js.Array2.t('a) => Js.Fn.arity1(('a => bool)) => Js.Array2.t('a);
let dropWhile: Js.Array2.t('a) => ('a => bool) => Js.Array2.t('a);
let updateUnsafeU: array('a) => int => Js.Fn.arity1(('a => 'a)) => unit;

i번째 인덱스의 값에 f를 수행한 결과를 in-place로 업데이트합니다. f는 old value를 받아 new value를 반환하는 함수입니다.

let updateUnsafe: array('a) => int => ('a => 'a) => unit;
let updateExnU: array('a) => int => Js.Fn.arity1(('a => 'a)) => unit;
let updateExn: array('a) => int => ('a => 'a) => unit;
let keepSome: array(option('a)) => array('a);

option타입의 배열에서 None을 제거하고, Some의 값을 꺼낸 결과의 배열을 반환합니다. 시간 복잡도: O(n)

keepSome([ Some(1), None, Some(3) ]) == [ 1, 3 ]
let groupBy: array('a) => ('a => 'b) => id:Belt.Map.id('b'c) => Belt.Map.t('b, array('a), 'c);

keyFn으로 그루핑된 Belt.Map을 반환합니다. ~id에는 Belt.Id.Comparable 모듈이 전달되어야 합니다. 일반적인 타입에 대한 Comparable 모듈은 Garter.Id를 참고하세요.

groupBy(
  [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
  x => x mod 3,
  ~id=Garter.Id.IntComparable,
)
let indexBy: array('a) => ('a => 'b) => id:Belt.Map.id('b'c) => Belt.Map.t('b'a'c);

indexFn의 결과값을 Belt.Map의 key로 할당한 값을 반환합니다. indexFn의 결과값이 중복되면 마지막으로 나온 값이 할당됩니다.

type t = {a:int, b:int}
indexBy(
  [ {a:1, b:1}, {a:1, b:2}, {a:2, b:2}, {a:3, b:3} ],
  keyFn=x => x.a,
  ~id=Garter.Id.IntComparable,
)
// (1, {a:1, b:2}), (2, {a:2, b:2}), (3, {a:3, b:3})
let frequencies: array('a) => id:Belt.Map.id('a'b) => Belt.Map.t('a, int, 'b);

배열에 들어있는 값들의 빈도를 구하여 Map으로 반환합니다.

let distinct: array('a) => id:Belt.Set.id('a'b) => array('a);

먼저 등장하는 순서를 유지하면서 중복 원소를 제거합니다.

let scan: array('a) => 'b => ('b => 'a => 'b) => array('b);

reduce와 비슷하나 중간 결과를 모두 포함한 array를 반환합니다.

let reduce1U: array('a) => Js.Fn.arity2(('a => 'a => 'a)) => 'a;
let reduce1: array('a) => ('a => 'a => 'a) => 'a;
let minByU: array('a) => Js.Fn.arity2(('a => 'a => int)) => 'a;
let minBy: array('a) => ('a => 'a => int) => 'a;
let maxByU: array('a) => Js.Fn.arity2(('a => 'a => int)) => 'a;
let maxBy: array('a) => ('a => 'a => int) => 'a;
let chunk: array('a) => int => array(array('a));

배열을 일정 크기로 자른 2차원 배열을 반환합니다.

chunk([ 1, 2, 3, 4 ], 2)    // -> [ [ 1, 2 ], [ 3, 4 ] ]
chunk([ 1, 2, 3, 4, 5 ], 2) // -> [ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]
chunk([ 1, 2, 3, 4, 5 ], 6) // -> [ [ 1, 2, 3, 4, 5 ] ]
let randomOne: array('a) => option('a);

임의의 원소 1개를 무작위로 추출합니다. 참고: https://clojuredocs.org/clojure.core/rand-nth

randomOne([#ice-cream, #steak, #apple]) // -> #apple
let randomSample: array('a) => float => array('a);

주어진 확률로 원소를 채택한 결과를 반환합니다. 참고: https://clojuredocs.org/clojure.core/random-sample

randomSample([1, 2, 3, 4, 5], 0.5) // -> [1, 2, 4]
let intersperse: array('a) => 'a => array('a);

두 번째 인자를 배열의 사이사이에 끼워넣은 결과를 반환합니다.

intersperse([1, 2, 3], 0) // -> [1, 0, 2, 0, 3]
module Int: { ... };
module String: { ... };