Skip to content

Commit 5ab144e

Browse files
committed
add iterator and asyncIterator forEach helpers
1 parent e9863e5 commit 5ab144e

11 files changed

+223
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Remove internal xxxU helper functions that are not needed anymore in uncurried mode. https://github.com/rescript-association/rescript-core/pull/191
99
- Rename `Object.empty` to `Object.make` for consistency.
1010
- Add dynamic `import`. https://github.com/rescript-association/rescript-core/pull/178
11+
- Add `Iterator.forEach` and `AsyncIterator.forEach` helpers for iterators.
1112

1213
## 1.0.0
1314

src/Core__AsyncIterator.mjs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,16 @@
11
// Generated by ReScript, PLEASE EDIT WITH CARE
2-
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
2+
3+
4+
async function forEach(iterator, f) {
5+
var iteratorDone = false;
6+
while(!iteratorDone) {
7+
var match = await iterator.next();
8+
f(match.value);
9+
iteratorDone = match.done;
10+
};
11+
}
12+
13+
export {
14+
forEach ,
15+
}
16+
/* No side effect */

src/Core__AsyncIterator.res

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@ type value<'a> = {
66
}
77

88
@send external next: t<'a> => promise<value<'a>> = "next"
9+
10+
let forEach = async (iterator, f) => {
11+
let iteratorDone = ref(false)
12+
13+
while !iteratorDone.contents {
14+
let {done, value} = await iterator->next
15+
f(value)
16+
iteratorDone := done
17+
}
18+
}

src/Core__AsyncIterator.resi

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,19 @@ let processMyAsyncIterator = async () => {
5858
*/
5959
@send
6060
external next: t<'a> => promise<value<'a>> = "next"
61+
62+
/**
63+
`forEach(iterator, fn)` consumes all values in the async iterator and runs the callback `fn` for each value.
64+
65+
See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
66+
67+
## Examples
68+
```rescript
69+
await someAsyncIterator->AsyncIterator.forEach(value => {
70+
if value > 10 {
71+
Console.log("More than 10!")
72+
}
73+
})
74+
```
75+
*/
76+
let forEach: (t<'a>, option<'a> => unit) => promise<unit>

src/Core__Iterator.mjs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,16 @@
11
// Generated by ReScript, PLEASE EDIT WITH CARE
2-
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
2+
3+
4+
function forEach(iterator, f) {
5+
var iteratorDone = false;
6+
while(!iteratorDone) {
7+
var match = iterator.next();
8+
f(match.value);
9+
iteratorDone = match.done;
10+
};
11+
}
12+
13+
export {
14+
forEach ,
15+
}
16+
/* No side effect */

src/Core__Iterator.res

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@ type value<'a> = {
88
@send external next: t<'a> => value<'a> = "next"
99
external toArray: t<'a> => array<'a> = "Array.from"
1010
external toArrayWithMapper: (t<'a>, 'a => 'b) => array<'b> = "Array.from"
11+
12+
let forEach = (iterator, f) => {
13+
let iteratorDone = ref(false)
14+
15+
while !iteratorDone.contents {
16+
let {done, value} = iterator->next
17+
f(value)
18+
iteratorDone := done
19+
}
20+
}

src/Core__Iterator.resi

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,19 @@ Console.log(mapKeysAsArray) // Logs [7, 8] to the console.
7979
```
8080
*/
8181
external toArrayWithMapper: (t<'a>, 'a => 'b) => array<'b> = "Array.from"
82+
83+
/**
84+
`forEach(iterator, fn)` consumes all values in the iterator and runs the callback `fn` for each value.
85+
86+
See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
87+
88+
## Examples
89+
```rescript
90+
someIterator->Iterator.forEach(value => {
91+
if value > 10 {
92+
Console.log("More than 10!")
93+
}
94+
})
95+
```
96+
*/
97+
let forEach: (t<'a>, option<'a> => unit) => unit

test/IteratorTests.mjs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Generated by ReScript, PLEASE EDIT WITH CARE
2+
3+
import * as Test from "./Test.mjs";
4+
import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
5+
import * as Core__Iterator from "../src/Core__Iterator.mjs";
6+
import * as Core__AsyncIterator from "../src/Core__AsyncIterator.mjs";
7+
8+
var eq = Caml_obj.equal;
9+
10+
var iterator = ((() => {
11+
var array1 = ['a', 'b', 'c'];
12+
var iterator1 = array1[Symbol.iterator]();
13+
return iterator1
14+
})());
15+
16+
var syncResult = {
17+
contents: undefined
18+
};
19+
20+
Core__Iterator.forEach(iterator, (function (v) {
21+
if (v === "b") {
22+
syncResult.contents = "b";
23+
return ;
24+
}
25+
26+
}));
27+
28+
Test.run([
29+
[
30+
"IteratorTests.res",
31+
21,
32+
20,
33+
34
34+
],
35+
"Sync forEach"
36+
], syncResult.contents, eq, "b");
37+
38+
var asyncIterator = ((() => {
39+
var map1 = new Map();
40+
41+
map1.set('first', '1');
42+
map1.set('second', '2');
43+
44+
var iterator1 = map1[Symbol.iterator]();
45+
return iterator1;
46+
})());
47+
48+
var asyncResult = {
49+
contents: undefined
50+
};
51+
52+
await Core__AsyncIterator.forEach(asyncIterator, (function (v) {
53+
if (v !== undefined && v[0] === "second") {
54+
asyncResult.contents = "second";
55+
return ;
56+
}
57+
58+
}));
59+
60+
Test.run([
61+
[
62+
"IteratorTests.res",
63+
44,
64+
20,
65+
35
66+
],
67+
"Async forEach"
68+
], asyncResult.contents, eq, "second");
69+
70+
export {
71+
eq ,
72+
iterator ,
73+
syncResult ,
74+
asyncIterator ,
75+
asyncResult ,
76+
}
77+
/* iterator Not a pure module */

test/IteratorTests.res

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
open RescriptCore
2+
3+
let eq = (a, b) => a == b
4+
5+
let iterator: Iterator.t<string> = %raw(`
6+
(() => {
7+
var array1 = ['a', 'b', 'c'];
8+
var iterator1 = array1[Symbol.iterator]();
9+
return iterator1
10+
})()
11+
`)
12+
13+
let syncResult = ref(None)
14+
15+
iterator->Iterator.forEach(v => {
16+
if v === Some("b") {
17+
syncResult.contents = Some("b")
18+
}
19+
})
20+
21+
Test.run(__POS_OF__("Sync forEach"), syncResult.contents, eq, Some("b"))
22+
23+
let asyncIterator: AsyncIterator.t<(string, string)> = %raw(`
24+
(() => {
25+
var map1 = new Map();
26+
27+
map1.set('first', '1');
28+
map1.set('second', '2');
29+
30+
var iterator1 = map1[Symbol.iterator]();
31+
return iterator1;
32+
})()
33+
`)
34+
35+
let asyncResult = ref(None)
36+
37+
await asyncIterator->AsyncIterator.forEach(v => {
38+
switch v {
39+
| Some(("second", _value)) => asyncResult.contents = Some("second")
40+
| _ => ()
41+
}
42+
})
43+
44+
Test.run(__POS_OF__("Async forEach"), asyncResult.contents, eq, Some("second"))

test/TestSuite.mjs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Generated by ReScript, PLEASE EDIT WITH CARE
22

33
import * as IntTests from "./IntTests.mjs";
4+
import * as DictTests from "./DictTests.mjs";
45
import * as JsonTests from "./JsonTests.mjs";
56
import * as TestTests from "./TestTests.mjs";
67
import * as ArrayTests from "./ArrayTests.mjs";
@@ -9,6 +10,7 @@ import * as FloatTests from "./FloatTests.mjs";
910
import * as ObjectTests from "./ObjectTests.mjs";
1011
import * as PromiseTest from "./PromiseTest.mjs";
1112
import * as ResultTests from "./ResultTests.mjs";
13+
import * as IteratorTests from "./IteratorTests.mjs";
1214
import * as NullableTests from "./NullableTests.mjs";
1315
import * as TypedArrayTests from "./TypedArrayTests.mjs";
1416

@@ -66,12 +68,20 @@ var areSame = TypedArrayTests.areSame;
6668

6769
var o = TypedArrayTests.o;
6870

69-
var eq = FloatTests.eq;
70-
7171
var decodeJsonTest = JsonTests.decodeJsonTest;
7272

7373
var shouldHandleNullableValues = NullableTests.shouldHandleNullableValues;
7474

75+
var eq = IteratorTests.eq;
76+
77+
var iterator = IteratorTests.iterator;
78+
79+
var syncResult = IteratorTests.syncResult;
80+
81+
var asyncIterator = IteratorTests.asyncIterator;
82+
83+
var asyncResult = IteratorTests.asyncResult;
84+
7585
export {
7686
bign ,
7787
TestError ,
@@ -100,8 +110,12 @@ export {
100110
assertWillThrow ,
101111
areSame ,
102112
o ,
103-
eq ,
104113
decodeJsonTest ,
105114
shouldHandleNullableValues ,
115+
eq ,
116+
iterator ,
117+
syncResult ,
118+
asyncIterator ,
119+
asyncResult ,
106120
}
107121
/* IntTests Not a pure module */

test/TestSuite.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ include TypedArrayTests
99
include FloatTests
1010
include JsonTests
1111
include NullableTests
12+
include DictTests
13+
include IteratorTests

0 commit comments

Comments
 (0)