Skip to content

Use idiomatic new JS array immutable helpers #139

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 2 commits into from
May 23, 2023
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ This standard library is based on `rescript-js`, but with the tweaks and modific
- `findIndexOpt`/`lastIndexOf`/`indexOfOpt` are added, returning `None` instead of `-1` if the item searched for does not exist. These are in addition to `findIndex`/`lastIndexOf`, which still returns `-1` when the item you're looking for does not exist.
- `getUnsafe` added (copied from `Belt`).
- `setUnsafe` added (copied from `Belt`).
- `reverse` added (copied from `Belt`), in addition to existing `reverseInPlace`. `reverseInPlace` is zero cost but does not produce a new array. `reverse` does produce a new array.
- `sort`, `toSorted`, `reverse`, `toReversed`, `splice`, `toSpliced` are the same as their JS counterpart (mutable and immutable, respectively).
- `keepMap` is added from `Belt`, but **renamed to `filterMap`**. Rationale: `filterMap` is closer to the JS convention of naming. It's also available in other languages like Rust. `keep` et al can confuse beginners, who're bound to be looking for `filter` style names since that's what JS has.
- `shuffle` and `shuffleInPlace` are added (copied from `Belt`).
- `flatMap` added (copied from `Belt`, but using native `map` and `concat` functions).
Expand Down
17 changes: 0 additions & 17 deletions src/Core__Array.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ function lastIndexOfOpt(arr, item) {

}

function sort(arr, cmp) {
var result = arr.slice();
result.sort(cmp);
return result;
}

function reduce(arr, init, f) {
return arr.reduce(f, init);
}
Expand Down Expand Up @@ -76,15 +70,6 @@ function swapUnsafe(xs, i, j) {
xs[j] = tmp;
}

function reverse(xs) {
var len = xs.length;
var result = new Array(len);
for(var i = 0; i < len; ++i){
result[i] = xs[(len - 1 | 0) - i | 0];
}
return result;
}

function shuffleInPlace(xs) {
var len = xs.length;
for(var i = 0; i < len; ++i){
Expand Down Expand Up @@ -141,15 +126,13 @@ function findMap(arr, f) {
export {
make ,
fromInitializer ,
sort ,
indexOfOpt ,
lastIndexOfOpt ,
reduce ,
reduceWithIndex ,
reduceRight ,
reduceRightWithIndex ,
findIndexOpt ,
reverse ,
filterMap ,
keepSome ,
shuffle ,
Expand Down
29 changes: 10 additions & 19 deletions src/Core__Array.res
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,18 @@ external copyWithin: (array<'a>, ~target: int, ~start: int, ~end: int) => array<

@variadic @send external pushMany: (array<'a>, array<'a>) => unit = "push"

@send external reverseInPlace: array<'a> => unit = "reverse"
@send external reverse: array<'a> => unit = "reverse"
@send external toReversed: array<'a> => array<'a> = "toReversed"

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

@variadic @send
external spliceInPlace: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => unit =
"splice"
external splice: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => unit = "splice"
@variadic @send
external toSpliced: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => array<'a> =
"toSpliced"

@send external with: (array<'a>, int, 'a) => array<'a> = "with"

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

Expand Down Expand Up @@ -92,13 +97,8 @@ let lastIndexOfOpt = (arr, item) =>
@send external sliceToEnd: (array<'a>, ~start: int) => array<'a> = "slice"
@send external copy: array<'a> => array<'a> = "slice"

@send external sortInPlace: (array<'a>, ('a, 'a) => int) => unit = "sort"

let sort = (arr, cmp) => {
let result = copy(arr)
sortInPlace(result, cmp)
result
}
@send external sort: (array<'a>, ('a, 'a) => int) => unit = "sort"
@send external toSorted: (array<'a>, ('a, 'a) => int) => array<'a> = "toSorted"

@send external toString: array<'a> => string = "toString"
@send external toLocaleString: array<'a> => string = "toLocaleString"
Expand Down Expand Up @@ -154,15 +154,6 @@ let swapUnsafe = (xs, i, j) => {
setUnsafe(xs, j, tmp)
}

let reverse = xs => {
let len = length(xs)
let result = makeUninitializedUnsafe(len)
for i in 0 to len - 1 {
setUnsafe(result, i, getUnsafe(xs, len - 1 - i))
}
result
}

let shuffleInPlace = xs => {
let len = length(xs)
for i in 0 to len - 1 {
Expand Down
46 changes: 28 additions & 18 deletions src/Core__Array.resi
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ Console.log(someArray) // ["hi", "hello", "yay", "wehoo"]
external pushMany: (array<'a>, array<'a>) => unit = "push"

/**
`reverseInPlace(array)` reverses the order of the items in the array.
`reverse(array)` reverses the order of the items in `array`.

Beware this will *mutate* the array.

Expand All @@ -174,13 +174,13 @@ See [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Re
## Examples
```rescript
let someArray = ["hi", "hello"]
someArray->Array.reverseInPlace
someArray->Array.reverse

Console.log(someArray) // ["hello", "h1"]
```
*/
@send
external reverseInPlace: array<'a> => unit = "reverse"
external reverse: array<'a> => unit = "reverse"

/**
`shift(array)` removes the first item in the array, and returns it.
Expand All @@ -201,22 +201,24 @@ Console.log(someArray) // ["hello"]. Notice first item is gone.
external shift: array<'a> => option<'a> = "shift"

/**
`sort(array, comparator)` returns a new, sorted array from `array`, using the provided `comparator` function.
`toSorted(array, comparator)` returns a new, sorted array from `array`, using the `comparator` function.

See [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN.
See [`Array.toSorted`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted) on MDN.

## Examples
```rescript
let someArray = [3, 2, 1]
let sortedArray = someArray->Array.sort((a, b) => a > b ? 1 : -1)
let sorted = someArray->Array.toSorted((a, b) => a - b)

Console.log(sortedArray) // [1, 2, 3]
Console.log(sorted) // [1, 2, 3]
Console.log(someArray) // [3, 2, 1]. Original unchanged
```
*/
let sort: (array<'a>, ('a, 'a) => int) => array<'a>
@send
external toSorted: (array<'a>, ('a, 'a) => int) => array<'a> = "toSorted"

/**
`sortInPlace(array, comparator)` sorts `array` using the `comparator` function.
`sort(array, comparator)` sorts `array` in-place using the `comparator` function.

Beware this will *mutate* the array.

Expand All @@ -225,16 +227,22 @@ See [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer
## Examples
```rescript
let someArray = [3, 2, 1]
someArray->Array.sortInPlace((a, b) => a > b ? 1 : -1)
someArray->Array.sort((a, b) => a - b)

Console.log(someArray) // [1, 2, 3]
```
*/
@send
external sortInPlace: (array<'a>, ('a, 'a) => int) => unit = "sort"
external sort: (array<'a>, ('a, 'a) => int) => unit = "sort"

@variadic @send
external splice: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => unit = "splice"

@variadic @send
external spliceInPlace: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => unit =
"splice"
external toSpliced: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => array<'a> =
"toSpliced"

@send external with: (array<'a>, int, 'a) => array<'a> = "with"

/**
`unshift(array, item)` inserts a new item at the start of the array.
Expand Down Expand Up @@ -805,7 +813,7 @@ Console.log(array[1]) // "Hello"
external setUnsafe: (array<'a>, int, 'a) => unit = "%array_unsafe_set"

/**
`findIndexOpt(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.
`findIndexOpt(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.

Returns `None` if no item matches.

Expand All @@ -826,19 +834,21 @@ switch array->Array.findIndexOpt(item => item == ReScript) {
let findIndexOpt: (array<'a>, 'a => bool) => option<int>

/**
`reverse(array)` creates a new array with all items from `array` in reversed order.
`toReversed(array)` creates a new array with all items from `array` in reversed order.

See [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) on MDN.
See [`Array.toReversed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed) on MDN.

## Examples
```rescript
let someArray = ["hi", "hello"]
let reversed = someArray->Array.reverse
let reversed = someArray->Array.toReversed

Console.log(reversed) // ["hello", "h1"]
Console.log(someArray) // ["h1", "hello"]. Original unchanged
```
*/
let reverse: array<'a> => array<'a>
@send
external toReversed: array<'a> => array<'a> = "toReversed"

/**
`get(array, index)` returns the element at `index` of `array`.
Expand Down
2 changes: 1 addition & 1 deletion src/Core__List.res
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ let setAssoc = (xs, x, k, eq) => setAssocU(xs, x, k, (. a, b) => eq(a, b))

let sort = (xs, cmp) => {
let arr = toArray(xs)
Core__Array.sortInPlace(arr, cmp)
Core__Array.sort(arr, cmp)
fromArray(arr)
}

Expand Down
9 changes: 7 additions & 2 deletions src/typed-arrays/Core__TypedArray.res
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ external copyWithin: (t<'a>, ~target: int, ~start: int, ~end: int) => array<'a>
@send external fillInPlaceToEnd: (t<'a>, 'a, ~start: int) => t<'a> = "fill"
@send external fillInPlace: (t<'a>, 'a, ~start: int, ~end: int) => t<'a> = "fill"

@send external reverseInPlace: t<'a> => t<'a> = "reverse"
@send external sortInPlace: (t<'a>, ('a, 'a) => int) => t<'a> = "sort"
@send external reverse: t<'a> => unit = "reverse"
@send external toReversed: t<'a> => t<'a> = "toReversed"

@send external sort: (t<'a>, ('a, 'a) => int) => unit = "sort"
@send external toSorted: (t<'a>, ('a, 'a) => int) => t<'a> = "toSorted"

@send external with: (t<'a>, int, 'a) => t<'a> = "with"

@send external includes: (t<'a>, 'a) => bool = "includes"

Expand Down