Skip to content

Array additions #49

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

Merged
merged 19 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a882beb
feat(array): add findMap
glennsl Feb 18, 2023
31c8f64
feat(array): add init
glennsl Feb 18, 2023
307da89
feat(array): add make
glennsl Feb 18, 2023
12402ae
feat(array): add keepSome
glennsl Feb 18, 2023
2370ea6
refactor(array): bind to flatMap instead of reimplementing it
glennsl Feb 18, 2023
aa06078
refactor(array/make): use fillAllInPlace instead of manual loop
glennsl Feb 18, 2023
e02724c
feat(array): use labelled argument for length in make and init
glennsl Feb 19, 2023
c8a67b5
refactor(array): rename init -> fromInitializer
glennsl Feb 19, 2023
93110d0
test(array): add tests for non-native functions
glennsl Feb 26, 2023
0090ab6
refactor(array): bind to native reduce instead of reimplementing it
glennsl Feb 26, 2023
a2e2df9
refactor(array): replace reduceReverse with native binding to reduceR…
glennsl Feb 26, 2023
3042949
refactor(array): use native reduceWithIndex instead of reimplementing it
glennsl Feb 26, 2023
8eb7433
feat(array): add reduceRightWithIndex
glennsl Feb 26, 2023
b2f539e
docs(array): add docs for make, fromInitializer, findMap and keepSome
glennsl Feb 26, 2023
ffc18ee
docs(changelog): update changelog for array additions
glennsl Feb 26, 2023
85ce08b
Merge branch 'main' into feat/array-additions
glennsl Feb 26, 2023
b80a80f
docs(array): fix docstring fro keepSome
glennsl Feb 28, 2023
6d4f256
fix(array): reorder args of reduce functions for better te inference
glennsl Feb 28, 2023
616279f
refactor(array): consistent type variable naming in reduce functions
glennsl Feb 28, 2023
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
- Change `Float.parseFloat` signature. Now accepts only string. https://github.com/rescript-association/rescript-core/pull/54
- Add `getExn`, `getUnsafe`, `getWithDefault`, `map`, `mapWithDefault` and `flatMap` to `Nullable`. https://github.com/rescript-association/rescript-core/pull/67
- Add `getExn`, `getUnsafe`, `getWithDefault`, `map`, `mapWithDefault` and `flatMap` to `Null`. https://github.com/rescript-association/rescript-core/pull/73
- Add `make`, `fromInitializer`, `findMap`, `keepSome`, `reduceRight` and `reduceRightWithIndex`. https://github.com/rescript-association/rescript-core/pull/49
- Remove `reduceReverse` in favor of `reduceRight`. https://github.com/rescript-association/rescript-core/pull/49
- Fixed type signatures of `reduce` and `reduceWithIndex`. https://github.com/rescript-association/rescript-core/pull/49

### Documentation

Expand Down
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
"clean": "rescript clean",
"build": "rescript",
"watch": "rescript build -w",
"test": "node test/PromiseTest.mjs && node test/TempTests.mjs"
"test": "node test/TestSuite.mjs && node test/TempTests.mjs"
},
"keywords": [
"rescript"
],
"keywords": ["rescript"],
"homepage": "https://github.com/rescript-association/rescript-core",
"author": "ReScript Team",
"license": "MIT",
Expand Down
82 changes: 56 additions & 26 deletions src/Core__Array.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,26 @@
import * as Curry from "rescript/lib/es6/curry.js";
import * as Js_math from "rescript/lib/es6/js_math.js";
import * as Caml_option from "rescript/lib/es6/caml_option.js";
import * as Caml_splice_call from "rescript/lib/es6/caml_splice_call.js";

function make(length, x) {
if (length <= 0) {
return [];
}
var arr = new Array(length);
arr.fill(x);
return arr;
}

function fromInitializer(length, f) {
if (length <= 0) {
return [];
}
var arr = new Array(length);
for(var i = 0; i < length; ++i){
arr[i] = Curry._1(f, i);
}
return arr;
}

function indexOfOpt(arr, item) {
var index = arr.indexOf(item);
Expand All @@ -27,31 +46,20 @@ function sort(arr, cmp) {
return result;
}

function reduce(a, x, f) {
var f$1 = Curry.__2(f);
var r = x;
for(var i = 0 ,i_finish = a.length; i < i_finish; ++i){
r = f$1(r, a[i]);
}
return r;
function reduce(arr, init, f) {
return arr.reduce(f, init);
}

function reduceWithIndex(a, x, f) {
var f$1 = Curry.__3(f);
var r = x;
for(var i = 0 ,i_finish = a.length; i < i_finish; ++i){
r = f$1(r, a[i], i);
}
return r;
function reduceWithIndex(arr, init, f) {
return arr.reduce(f, init);
}

function reduceReverse(a, x, f) {
var f$1 = Curry.__2(f);
var r = x;
for(var i = a.length - 1 | 0; i >= 0; --i){
r = f$1(r, a[i]);
}
return r;
function reduceRight(arr, init, f) {
return arr.reduceRight(f, init);
}

function reduceRightWithIndex(arr, init, f) {
return arr.reduceRight(f, init);
}

function findIndexOpt(array, finder) {
Expand Down Expand Up @@ -108,22 +116,44 @@ function filterMap(a, f) {
return r;
}

function flatMap(a, f) {
return Caml_splice_call.spliceObjApply([], "concat", [a.map(f)]);
function keepSome(__x) {
return filterMap(__x, (function (x) {
return x;
}));
}

function findMap(arr, f) {
var _i = 0;
while(true) {
var i = _i;
if (i === arr.length) {
return ;
}
var r = Curry._1(f, arr[i]);
if (r !== undefined) {
return r;
}
_i = i + 1 | 0;
continue ;
};
}

export {
make ,
fromInitializer ,
sort ,
indexOfOpt ,
lastIndexOfOpt ,
reduce ,
reduceReverse ,
reduceWithIndex ,
reduceRight ,
reduceRightWithIndex ,
findIndexOpt ,
reverse ,
filterMap ,
keepSome ,
shuffle ,
shuffleInPlace ,
flatMap ,
findMap ,
}
/* No side effect */
94 changes: 55 additions & 39 deletions src/Core__Array.res
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@new external makeUninitializedUnsafe: int => array<'a> = "Array"
@set external truncateToLengthUnsafe: (array<'a>, int) => unit = "length"
external getUnsafe: (array<'a>, int) => 'a = "%array_unsafe_get"
external setUnsafe: (array<'a>, int, 'a) => unit = "%array_unsafe_set"

Expand All @@ -11,6 +13,32 @@ external fromArrayLikeWithMap: (Js.Array2.array_like<'a>, 'a => 'b) => array<'b>
@val external fromIterator: Core__Iterator.t<'a> => array<'a> = "Array.from"
@val external fromIteratorWithMap: (Core__Iterator.t<'a>, 'a => 'b) => array<'b> = "Array.from"

@send external fillAllInPlace: (array<'a>, 'a) => unit = "fill"

@send external fillInPlaceToEnd: (array<'a>, 'a, ~start: int) => unit = "fill"

@send external fillInPlace: (array<'a>, 'a, ~start: int, ~end: int) => unit = "fill"

let make = (~length, x) =>
if length <= 0 {
[]
} else {
let arr = makeUninitializedUnsafe(length)
arr->fillAllInPlace(x)
arr
}

let fromInitializer = (~length, f) =>
if length <= 0 {
[]
} else {
let arr = makeUninitializedUnsafe(length)
for i in 0 to length - 1 {
arr->setUnsafe(i, f(i))
}
arr
}

@val external isArray: 'a => bool = "Array.isArray"

@get external length: array<'a> => int = "length"
Expand All @@ -23,12 +51,6 @@ external copyWithinToEnd: (array<'a>, ~target: int, ~start: int) => array<'a> =
@send
external copyWithin: (array<'a>, ~target: int, ~start: int, ~end: int) => array<'a> = "copyWithin"

@send external fillAllInPlace: (array<'a>, 'a) => unit = "fill"

@send external fillInPlaceToEnd: (array<'a>, 'a, ~start: int) => unit = "fill"

@send external fillInPlace: (array<'a>, 'a, ~start: int, ~end: int) => unit = "fill"

@send external pop: array<'a> => option<'a> = "pop"

@send external push: (array<'a>, 'a) => unit = "push"
Expand Down Expand Up @@ -105,35 +127,16 @@ let sort = (arr, cmp) => {
@send external map: (array<'a>, 'a => 'b) => array<'b> = "map"
@send external mapWithIndex: (array<'a>, ('a, int) => 'b) => array<'b> = "map"

let reduceU = (a, x, f) => {
let r = ref(x)
for i in 0 to length(a) - 1 {
r.contents = f(. r.contents, getUnsafe(a, i))
}
r.contents
}

let reduce = (a, x, f) => reduceU(a, x, (. a, b) => f(a, b))

let reduceWithIndexU = (a, x, f) => {
let r = ref(x)
for i in 0 to length(a) - 1 {
r.contents = f(. r.contents, getUnsafe(a, i), i)
}
r.contents
}

let reduceWithIndex = (a, x, f) => reduceWithIndexU(a, x, (. a, b, c) => f(a, b, c))

let reduceReverseU = (a, x, f) => {
let r = ref(x)
for i in length(a) - 1 downto 0 {
r.contents = f(. r.contents, getUnsafe(a, i))
}
r.contents
}

let reduceReverse = (a, x, f) => reduceReverseU(a, x, (. a, b) => f(a, b))
@send external reduce: (array<'b>, ('a, 'b) => 'a, 'a) => 'a = "reduce"
let reduce = (arr, init, f) => reduce(arr, f, init)
@send external reduceWithIndex: (array<'b>, ('a, 'b, int) => 'a, 'a) => 'a = "reduce"
let reduceWithIndex = (arr, init, f) => reduceWithIndex(arr, f, init)
@send
external reduceRight: (array<'b>, ('a, 'b) => 'a, 'a) => 'a = "reduceRight"
let reduceRight = (arr, init, f) => reduceRight(arr, f, init)
@send
external reduceRightWithIndex: (array<'b>, ('a, 'b, int) => 'a, 'a) => 'a = "reduceRight"
let reduceRightWithIndex = (arr, init, f) => reduceRightWithIndex(arr, f, init)

@send external some: (array<'a>, 'a => bool) => bool = "some"
@send external someWithIndex: (array<'a>, ('a, int) => bool) => bool = "some"
Expand All @@ -151,8 +154,6 @@ let findIndexOpt = (array: array<'a>, finder: 'a => bool): option<int> =>
| index => Some(index)
}

@new external makeUninitializedUnsafe: int => array<'a> = "Array"
@set external truncateToLengthUnsafe: (array<'a>, int) => unit = "length"
let swapUnsafe = (xs, i, j) => {
let tmp = getUnsafe(xs, i)
setUnsafe(xs, i, getUnsafe(xs, j))
Expand Down Expand Up @@ -200,7 +201,22 @@ let filterMapU = (a, f) => {

let filterMap = (a, f) => filterMapU(a, (. a) => f(a))

// TODO: Change this implementation?
let flatMap = (a, f) => []->concatMany(map(a, f))
let keepSome = filterMap(_, x => x)

@send external flatMap: (array<'a>, 'a => array<'b>) => array<'b> = "flatMap"

let findMap = (arr, f) => {
let rec loop = i =>
if i == arr->length {
None
} else {
switch f(getUnsafe(arr, i)) {
| None => loop(i + 1)
| Some(_) as r => r
}
}

loop(0)
}

@send external at: (array<'a>, int) => option<'a> = "at"
Loading