Skip to content

Commit 674cc9e

Browse files
Stdlib: Add Array.filterMapWithIndex (#7876)
* Add filterMapWithIndex to Stdlib * Changelog
1 parent 85b20db commit 674cc9e

File tree

7 files changed

+91
-0
lines changed

7 files changed

+91
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#### :rocket: New Feature
2222

23+
- Add `Array.filterMapWithIndex` to Stdlib. https://github.com/rescript-lang/rescript/pull/7876
24+
2325
#### :bug: Bug fix
2426

2527
- Fix code generation for emojis in polyvars and labels. https://github.com/rescript-lang/rescript/pull/7853

packages/@rescript/runtime/Stdlib_Array.res

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,23 @@ let filterMap = (a, f) => {
273273

274274
let keepSome = filterMap(_, x => x)
275275

276+
let filterMapWithIndex = (a, f) => {
277+
let l = length(a)
278+
let r = makeUninitializedUnsafe(l)
279+
let j = ref(0)
280+
for i in 0 to l - 1 {
281+
let v = getUnsafe(a, i)
282+
switch f(v, i) {
283+
| None => ()
284+
| Some(v) =>
285+
setUnsafe(r, j.contents, v)
286+
j.contents = j.contents + 1
287+
}
288+
}
289+
truncateToLengthUnsafe(r, j.contents)
290+
r
291+
}
292+
276293
@send external flatMap: (array<'a>, 'a => array<'b>) => array<'b> = "flatMap"
277294
@send external flatMapWithIndex: (array<'a>, ('a, int) => array<'b>) => array<'b> = "flatMap"
278295

packages/@rescript/runtime/Stdlib_Array.resi

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,24 @@ Array.filterMap([], n => mod(n, 2) == 0 ? Some(n * n) : None) == []
11931193
*/
11941194
let filterMap: (array<'a>, 'a => option<'b>) => array<'b>
11951195

1196+
/**
1197+
`filterMapWithIndex(array, fn)`
1198+
1199+
Calls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.
1200+
1201+
## Examples
1202+
1203+
```rescript
1204+
["Hello", "Hi", "Good bye"]->Array.filterMapWithIndex((item, index) =>
1205+
switch item {
1206+
| "Hello" => Some(index)
1207+
| _ => None
1208+
}
1209+
) == [0]
1210+
```
1211+
*/
1212+
let filterMapWithIndex: (array<'a>, ('a, int) => option<'b>) => array<'b>
1213+
11961214
/**
11971215
`keepSome(arr)`
11981216

packages/@rescript/runtime/lib/es6/Stdlib_Array.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,23 @@ function keepSome(__x) {
162162
return filterMap(__x, x => x);
163163
}
164164

165+
function filterMapWithIndex(a, f) {
166+
let l = a.length;
167+
let r = new Array(l);
168+
let j = 0;
169+
for (let i = 0; i < l; ++i) {
170+
let v = a[i];
171+
let v$1 = f(v, i);
172+
if (v$1 !== undefined) {
173+
r[j] = Primitive_option.valFromOption(v$1);
174+
j = j + 1 | 0;
175+
}
176+
177+
}
178+
r.length = j;
179+
return r;
180+
}
181+
165182
function findMap(arr, f) {
166183
let _i = 0;
167184
while (true) {
@@ -197,6 +214,7 @@ export {
197214
findIndexOpt,
198215
findLastIndexOpt,
199216
filterMap,
217+
filterMapWithIndex,
200218
keepSome,
201219
toShuffled,
202220
shuffle,

packages/@rescript/runtime/lib/js/Stdlib_Array.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,23 @@ function keepSome(__x) {
162162
return filterMap(__x, x => x);
163163
}
164164

165+
function filterMapWithIndex(a, f) {
166+
let l = a.length;
167+
let r = new Array(l);
168+
let j = 0;
169+
for (let i = 0; i < l; ++i) {
170+
let v = a[i];
171+
let v$1 = f(v, i);
172+
if (v$1 !== undefined) {
173+
r[j] = Primitive_option.valFromOption(v$1);
174+
j = j + 1 | 0;
175+
}
176+
177+
}
178+
r.length = j;
179+
return r;
180+
}
181+
165182
function findMap(arr, f) {
166183
let _i = 0;
167184
while (true) {
@@ -196,6 +213,7 @@ exports.reduceRightWithIndex = reduceRightWithIndex;
196213
exports.findIndexOpt = findIndexOpt;
197214
exports.findLastIndexOpt = findLastIndexOpt;
198215
exports.filterMap = filterMap;
216+
exports.filterMapWithIndex = filterMapWithIndex;
199217
exports.keepSome = keepSome;
200218
exports.toShuffled = toShuffled;
201219
exports.shuffle = shuffle;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ Path Array.
238238
"tags": [],
239239
"detail": "(array<'a>, ('a, 'a) => Ordering.t) => unit",
240240
"documentation": {"kind": "markdown", "value": "\n`sort(array, comparator)` sorts `array` in-place using the `comparator` function.\n\nBeware this will *mutate* the array.\n\nSee [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN.\n\n## Examples\n\n```rescript\nlet array = [3, 2, 1]\narray->Array.sort((a, b) => float(a - b))\narray == [1, 2, 3]\n```\n"}
241+
}, {
242+
"label": "filterMapWithIndex",
243+
"kind": 12,
244+
"tags": [],
245+
"detail": "(array<'a>, ('a, int) => option<'b>) => array<'b>",
246+
"documentation": {"kind": "markdown", "value": "\n`filterMapWithIndex(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]->Array.filterMapWithIndex((item, index) =>\n switch item {\n | \"Hello\" => Some(index)\n | _ => None\n }\n) == [0]\n```\n"}
241247
}, {
242248
"label": "length",
243249
"kind": 12,

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,18 @@ Path filt
374374
"range": {"start": {"line": 86, "character": 34}, "end": {"line": 86, "character": 35}},
375375
"newText": ""
376376
}]
377+
}, {
378+
"label": "->Array.filterMapWithIndex",
379+
"kind": 12,
380+
"tags": [],
381+
"detail": "(array<'a>, ('a, int) => option<'b>) => array<'b>",
382+
"documentation": {"kind": "markdown", "value": "\n`filterMapWithIndex(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]->Array.filterMapWithIndex((item, index) =>\n switch item {\n | \"Hello\" => Some(index)\n | _ => None\n }\n) == [0]\n```\n"},
383+
"sortText": "filterMapWithIndex",
384+
"insertText": "->Array.filterMapWithIndex",
385+
"additionalTextEdits": [{
386+
"range": {"start": {"line": 86, "character": 34}, "end": {"line": 86, "character": 35}},
387+
"newText": ""
388+
}]
377389
}, {
378390
"label": "->Array.filter",
379391
"kind": 12,

0 commit comments

Comments
 (0)