Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#### :rocket: New Feature

- Rewatch: add `--prod` flag to `build`, `watch`, and `clean` to skip dev-dependencies and dev sources (`"type": "dev"`), enabling builds in environments where dev packages aren't installed (e.g. after `pnpm install --prod`). https://github.com/rescript-lang/rescript/pull/8347
- Add `Dict.assignMany`, `Dict.concat`, `Dict.concatMany`, `Dict.concatAll`, `Array.concatAll` to the stdlib. https://github.com/rescript-lang/rescript/pull/8364

#### :bug: Bug fix

Expand Down
1 change: 1 addition & 0 deletions packages/@rescript/runtime/Stdlib_Array.res
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ external removeInPlace: (array<'a>, int, @as(1) _) => unit = "splice"

@send external concat: (array<'a>, array<'a>) => array<'a> = "concat"
@variadic @send external concatMany: (array<'a>, array<array<'a>>) => array<'a> = "concat"
let concatAll = arrays => concatMany([], arrays)

@send external flat: array<array<'a>> => array<'a> = "flat"

Expand Down
17 changes: 17 additions & 0 deletions packages/@rescript/runtime/Stdlib_Array.resi
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,23 @@ Console.log(someArray) // ["hi", "hello", "yay", "wehoo"]
@variadic @send
external concatMany: (array<'a>, array<array<'a>>) => array<'a> = "concat"

/**
`concatAll(arrays)` concatenates all arrays in `arrays`, creating a new array.

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

## Examples
```rescript
let arrays = [["hi", "hello"], ["yay"], ["wehoo"]]

let result = Array.concatAll(arrays)

arrays == [["hi", "hello"], ["yay"], ["wehoo"]]
result == ["hi", "hello", "yay", "wehoo"]
```
*/
let concatAll: array<array<'a>> => array<'a>

/**
`flat(arrays)` concatenates an array of arrays into a single array.

Expand Down
9 changes: 9 additions & 0 deletions packages/@rescript/runtime/Stdlib_Dict.res
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ external fromIterable: Stdlib_Iterable.t<(string, 'a)> => dict<'a> = "Object.fro

@val external assign: (dict<'a>, dict<'a>) => dict<'a> = "Object.assign"

@variadic @val external assignMany: (dict<'a>, array<dict<'a>>) => dict<'a> = "Object.assign"

@val external concat: (@as(json`{}`) _, dict<'a>, dict<'a>) => dict<'a> = "Object.assign"

@variadic @val
external concatMany: (@as(json`{}`) _, dict<'a>, array<dict<'a>>) => dict<'a> = "Object.assign"

@variadic @val external concatAll: (@as(json`{}`) _, array<dict<'a>>) => dict<'a> = "Object.assign"

@val external copy: (@as(json`{}`) _, dict<'a>) => dict<'a> = "Object.assign"

// Use %raw to support for..in which is a ~10% faster than .forEach
Expand Down
84 changes: 83 additions & 1 deletion packages/@rescript/runtime/Stdlib_Dict.resi
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ external valuesToArray: dict<'a> => array<'a> = "Object.values"
/**
`assign(dictionary1, dictionary2)` [shallowly](https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy) merges dictionary2 into dictionary1, and returns dictionary1.

Beware this will *mutate* dictionary1. If you're looking for a way to copy a dictionary, check out `Dict.copy`.
Beware this will *mutate* dictionary1. If you're looking for a fresh merged dictionary instead, check out `Dict.concat`.

## Examples
```rescript
Expand All @@ -242,6 +242,88 @@ Console.log(dict1->Dict.keysToArray) // Logs `["firstKey", "someKey", "someKey2"
@val
external assign: (dict<'a>, dict<'a>) => dict<'a> = "Object.assign"

/**
`assignMany(target, sources)` [shallowly](https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy) merges each dictionary in `sources` into `target`, and returns `target`.

Beware this will *mutate* `target`. Later dictionaries overwrite earlier ones. If you're looking for a fresh merged dictionary instead, check out `Dict.concatMany`.

## Examples
```rescript
let target = dict{"firstKey": 1}
let result = target->Dict.assignMany([
dict{"someKey": 2},
dict{"someKey": 3, "someKey2": 4},
])

result == dict{"firstKey": 1, "someKey": 3, "someKey2": 4}
(result === target) == true
```
*/
@variadic @val
external assignMany: (dict<'a>, array<dict<'a>>) => dict<'a> = "Object.assign"

/**
`concat(dictionary1, dictionary2)` [shallowly](https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy) merges `dictionary1` and `dictionary2` into a fresh dictionary, and returns the new dictionary.

Neither input dictionary is mutated. If both dictionaries contain the same key, the value from `dictionary2` overwrites the one from `dictionary1`.

## Examples
```rescript
let dict1 = dict{"firstKey": 1}
let dict2 = dict{"firstKey": 2, "someKey": 3}

let merged = dict1->Dict.concat(dict2)

dict1 == dict{"firstKey": 1}
merged == dict{"firstKey": 2, "someKey": 3}
(merged === dict1) == false
```
*/
@val
external concat: (@as(json`{}`) _, dict<'a>, dict<'a>) => dict<'a> = "Object.assign"

/**
`concatMany(target, sources)` [shallowly](https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy) merges `target` and each dictionary in `sources` into a fresh dictionary, and returns the new dictionary.

Neither `target` nor any dictionary in `sources` is mutated. Later dictionaries overwrite earlier ones when they contain the same key.

## Examples
```rescript
let target = dict{"firstKey": 1}
let merged = target->Dict.concatMany([
dict{"someKey": 2},
dict{"someKey": 3, "someKey2": 4},
])

target == dict{"firstKey": 1}
merged == dict{"firstKey": 1, "someKey": 3, "someKey2": 4}
(merged === target) == false
```
*/
@variadic @val
external concatMany: (@as(json`{}`) _, dict<'a>, array<dict<'a>>) => dict<'a> = "Object.assign"

/**
`concatAll(dictionaries)` [shallowly](https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy) merges all dictionaries in `dictionaries` into a fresh dictionary, and returns the new dictionary.

None of the input dictionaries are mutated. Later dictionaries overwrite earlier ones when they contain the same key. If `dictionaries` is empty, an empty dictionary is returned.

## Examples
```rescript
let dict1 = dict{"firstKey": 1}
let dict2 = dict{"someKey": 2}
let dict3 = dict{"someKey": 3, "someKey2": 4}

let merged = Dict.concatAll([dict1, dict2, dict3])

dict1 == dict{"firstKey": 1}
merged == dict{"firstKey": 1, "someKey": 3, "someKey2": 4}
(merged === dict1) == false
```
*/
@variadic @val
external concatAll: (@as(json`{}`) _, array<dict<'a>>) => dict<'a> = "Object.assign"

/**
`copy(dictionary)` [shallowly copies](https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy) the provided dictionary to a new dictionary.

Expand Down
5 changes: 5 additions & 0 deletions packages/@rescript/runtime/lib/es6/Stdlib_Array.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ function compare(a, b, cmp) {
}
}

function concatAll(arrays) {
return [].concat(...arrays);
}

function indexOfOpt(arr, item) {
let index = arr.indexOf(item);
if (index !== -1) {
Expand Down Expand Up @@ -264,6 +268,7 @@ export {
equal,
compare,
isEmpty,
concatAll,
indexOfOpt,
lastIndexOfOpt,
reduce,
Expand Down
5 changes: 5 additions & 0 deletions packages/@rescript/runtime/lib/js/Stdlib_Array.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ function compare(a, b, cmp) {
}
}

function concatAll(arrays) {
return [].concat(...arrays);
}

function indexOfOpt(arr, item) {
let index = arr.indexOf(item);
if (index !== -1) {
Expand Down Expand Up @@ -263,6 +267,7 @@ exports.fromInitializer = fromInitializer;
exports.equal = equal;
exports.compare = compare;
exports.isEmpty = isEmpty;
exports.concatAll = concatAll;
exports.indexOfOpt = indexOfOpt;
exports.lastIndexOfOpt = lastIndexOfOpt;
exports.reduce = reduce;
Expand Down
6 changes: 6 additions & 0 deletions tests/analysis_tests/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,12 @@ Path Array.
"tags": [],
"detail": "(array<'a>, array<'a>, ('a, 'a) => bool) => bool",
"documentation": {"kind": "markdown", "value": "\n`equal(left, right, predicate)` checks if the two arrays contain the same elements according to the equality `predicate`.\n\n## Examples\n\n```rescript\nArray.equal([1, 2, 3], [1, 2, 3], Int.equal) == true\nArray.equal([1, 2, 3], [1, 3, 2], Int.equal) == false\n```\n"}
}, {
"label": "concatAll",
"kind": 12,
"tags": [],
"detail": "array<array<'a>> => array<'a>",
"documentation": {"kind": "markdown", "value": "\n`concatAll(arrays)` concatenates all arrays in `arrays`, creating a new array.\n\nSee [`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) on MDN.\n\n## Examples\n```rescript\nlet arrays = [[\"hi\", \"hello\"], [\"yay\"], [\"wehoo\"]]\n\nlet result = Array.concatAll(arrays)\n\narrays == [[\"hi\", \"hello\"], [\"yay\"], [\"wehoo\"]]\nresult == [\"hi\", \"hello\", \"yay\", \"wehoo\"]\n```\n"}
}, {
"label": "joinUnsafe",
"kind": 12,
Expand Down
76 changes: 68 additions & 8 deletions tests/tests/src/stdlib/Stdlib_ArrayTests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -443,10 +443,70 @@ Test.run([
"c"
]);

let arrays = [
[
1,
2
],
[3],
[
4,
5
]
];

let result = Stdlib_Array.concatAll(arrays);

Test.run([
[
"Stdlib_ArrayTests.res",
121,
22,
53
],
"concatAll concatenates arrays"
], result, eq, [
1,
2,
3,
4,
5
]);

Test.run([
[
"Stdlib_ArrayTests.res",
123,
15,
57
],
"concatAll leaves source arrays unchanged"
], arrays, eq, [
[
1,
2
],
[3],
[
4,
5
]
]);

Test.run([
[
"Stdlib_ArrayTests.res",
130,
20,
39
],
"concatAll - empty"
], Stdlib_Array.concatAll([]), eq, []);

Test.run([
[
"Stdlib_ArrayTests.res",
118,
133,
13,
31
],
Expand All @@ -465,7 +525,7 @@ Test.run([
Test.run([
[
"Stdlib_ArrayTests.res",
125,
140,
13,
31
],
Expand All @@ -479,7 +539,7 @@ Test.run([
Test.run([
[
"Stdlib_ArrayTests.res",
132,
147,
13,
29
],
Expand Down Expand Up @@ -507,7 +567,7 @@ Test.run([
Test.run([
[
"Stdlib_ArrayTests.res",
139,
154,
13,
29
],
Expand All @@ -524,7 +584,7 @@ Test.run([
Test.run([
[
"Stdlib_ArrayTests.res",
145,
160,
20,
39
],
Expand All @@ -538,7 +598,7 @@ Test.run([
Test.run([
[
"Stdlib_ArrayTests.res",
146,
161,
20,
34
],
Expand All @@ -552,7 +612,7 @@ array.splice(1, 0, "foo");
Test.run([
[
"Stdlib_ArrayTests.res",
151,
166,
22,
49
],
Expand All @@ -567,7 +627,7 @@ let array$1 = [
Test.run([
[
"Stdlib_ArrayTests.res",
157,
172,
15,
43
],
Expand Down
15 changes: 15 additions & 0 deletions tests/tests/src/stdlib/Stdlib_ArrayTests.res
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,21 @@ Test.run(
["a", "b", "c"],
)

{
let arrays = [[1, 2], [3], [4, 5]]
let result = Array.concatAll(arrays)

Test.run(__POS_OF__("concatAll concatenates arrays"), result, eq, [1, 2, 3, 4, 5])
Test.run(
__POS_OF__("concatAll leaves source arrays unchanged"),
arrays,
eq,
[[1, 2], [3], [4, 5]],
)
}

Test.run(__POS_OF__("concatAll - empty"), Array.concatAll([]), eq, [])

Test.run(
__POS_OF__("Map.fromIterable"),
Map.fromIterable([("one", 1), ("two", 2)]->Array.asIterable)->Map.size,
Expand Down
Loading
Loading