Skip to content

Commit 2470f75

Browse files
DZakhtsnobip
andauthored
Add Array.removeInPlace (#7321)
* Add Array.removeInPlace * Update changelog * Add documentation * Commit new tests output * Fix analysis test * Update tests/analysis_tests/tests/test.sh Co-authored-by: Paul Tsnobiladzé <[email protected]> * Remove duplicated tests --------- Co-authored-by: Paul Tsnobiladzé <[email protected]>
1 parent 20fea08 commit 2470f75

File tree

7 files changed

+91
-2
lines changed

7 files changed

+91
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
- Add `Dict.has` and double `Dict.forEachWithKey`/`Dict.mapValues` performance. https://github.com/rescript-lang/rescript/pull/7316
1818
- Add popover attributes to JsxDOM.domProps. https://github.com/rescript-lang/rescript/pull/7317
19+
- Add `Array.removeInPlace` helper based on `splice`. https://github.com/rescript-lang/rescript/pull/7321
1920
- Add `inert` attribute to `JsxDOM.domProps`. https://github.com/rescript-lang/rescript/pull/7326
2021
- Make reanalyze exception tracking work with the new stdlib. https://github.com/rescript-lang/rescript/pull/7328
2122
- Fix Pervasive.max using boolean comparison for floats. https://github.com/rescript-lang/rescript/pull/7333

runtime/Stdlib_Array.res

+3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ external splice: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => u
108108
external toSpliced: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => array<'a> =
109109
"toSpliced"
110110

111+
@send
112+
external removeInPlace: (array<'a>, int, @as(1) _) => unit = "splice"
113+
111114
@send external with: (array<'a>, int, 'a) => array<'a> = "with"
112115

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

runtime/Stdlib_Array.resi

+20
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,26 @@ external splice: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => u
302302
external toSpliced: (array<'a>, ~start: int, ~remove: int, ~insert: array<'a>) => array<'a> =
303303
"toSpliced"
304304

305+
/**
306+
`removeInPlace(array, index)` removes the item at the specified `index` from `array`.
307+
308+
Beware this will *mutate* the array.
309+
310+
## Examples
311+
312+
```rescript
313+
let array = []
314+
array->Array.removeInPlace(0)
315+
assertEqual(array, []) // Removing from an empty array does nothing
316+
317+
let array2 = ["Hello", "Hi", "Good bye"]
318+
array2->Array.removeInPlace(1)
319+
assertEqual(array2, ["Hello", "Good bye"]) // Removes the item at index 1
320+
```
321+
*/
322+
@send
323+
external removeInPlace: (array<'a>, int, @as(1) _) => unit = "splice"
324+
305325
@send external with: (array<'a>, int, 'a) => array<'a> = "with"
306326

307327
/**

tests/analysis_tests/tests/src/expected/Completion.res.txt

+6
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,12 @@ Path Array.
514514
"tags": [],
515515
"detail": "(array<'a>, int) => option<'a>",
516516
"documentation": {"kind": "markdown", "value": "\n`get(array, index)` returns the element at `index` of `array`.\n\nReturns `None` if the index does not exist in the array. Equivalent to doing `array[index]` in JavaScript.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray\n->Array.get(0)\n->assertEqual(Some(\"Hello\"))\n\narray\n->Array.get(3)\n->assertEqual(None)\n```\n"}
517+
}, {
518+
"label": "removeInPlace",
519+
"kind": 12,
520+
"tags": [],
521+
"detail": "(array<'a>, int) => unit",
522+
"documentation": {"kind": "markdown", "value": "\n`removeInPlace(array, index)` removes the item at the specified `index` from `array`.\n\nBeware this will *mutate* the array.\n\n## Examples\n\n```rescript\nlet array = []\narray->Array.removeInPlace(0)\nassertEqual(array, []) // Removing from an empty array does nothing\n\nlet array2 = [\"Hello\", \"Hi\", \"Good bye\"]\narray2->Array.removeInPlace(1)\nassertEqual(array2, [\"Hello\", \"Good bye\"]) // Removes the item at index 1\n```\n "}
517523
}, {
518524
"label": "pushMany",
519525
"kind": 12,

tests/analysis_tests/tests/test.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ reset='\033[0m'
2222

2323
diff=$(git ls-files --modified src/expected)
2424
if [[ $diff = "" ]]; then
25-
printf "${successGreen}✅ No unstaged tests difference.${reset}\n"
25+
printf "${successGreen}✅ No analysis_tests snapshot changes detected.${reset}\n"
2626
else
27-
printf "${warningYellow}⚠️ There are unstaged differences in tests/! Did you break a test?\n${diff}\n${reset}"
27+
printf "${warningYellow}⚠️ The analysis_tests snapshot doesn't match. Double check that the output is correct, run 'make analysis_tests' and stage the diff.\n${diff}\n${reset}"
2828
git --no-pager diff src/expected
2929
exit 1
3030
fi

tests/tests/src/core/Core_ArrayTests.mjs

+38
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,44 @@ Test.run([
457457
"last - empty"
458458
], Stdlib_Array.last([]), eq, undefined);
459459

460+
let array = [];
461+
462+
array.splice(1, 0, "foo");
463+
464+
Test.run([
465+
[
466+
"Core_ArrayTests.res",
467+
116,
468+
22,
469+
49
470+
],
471+
"splice - Insert no delete"
472+
], array, eq, ["foo"]);
473+
474+
let array$1 = [
475+
"bar",
476+
"baz"
477+
];
478+
479+
Test.run([
480+
[
481+
"Core_ArrayTests.res",
482+
122,
483+
15,
484+
43
485+
],
486+
"splice - Insert and delete"
487+
], [
488+
(array$1.splice(1, 1, "foo"), undefined),
489+
array$1
490+
], eq, [
491+
undefined,
492+
[
493+
"bar",
494+
"foo"
495+
]
496+
]);
497+
460498
export {
461499
eq,
462500
}

tests/tests/src/core/Core_ArrayTests.res

+21
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,24 @@ Test.run(
109109

110110
Test.run(__POS_OF__("last - with items"), [1, 2, 3]->Array.last, eq, Some(3))
111111
Test.run(__POS_OF__("last - empty"), []->Array.last, eq, None)
112+
113+
{
114+
let array = []
115+
array->Array.splice(~start=1, ~remove=0, ~insert=["foo"])
116+
Test.run(__POS_OF__("splice - Insert no delete"), array, eq, ["foo"])
117+
}
118+
119+
{
120+
let array = ["bar", "baz"]
121+
Test.run(
122+
__POS_OF__("splice - Insert and delete"),
123+
(array->Array.splice(~start=1, ~remove=1, ~insert=["foo"]), array),
124+
eq,
125+
(
126+
// Even though original .splice returns an array with the removed items,
127+
// the binding returns unit so there's no confusion about it mutating the original array.
128+
(),
129+
["bar", "foo"],
130+
),
131+
)
132+
}

0 commit comments

Comments
 (0)