Skip to content

Commit eea5e0d

Browse files
committed
add iterator and asyncIterator forEach helpers
1 parent 9edbc4d commit eea5e0d

12 files changed

+225
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Next version
44

5+
- Add `Iterator.forEach` and `AsyncIterator.forEach` helpers for iterators.
56
- Add `Dict.getUnsafe` https://github.com/rescript-association/rescript-core/pull/167
67

78
### Documentation

src/Core__AsyncIterator.mjs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
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+
import * as Curry from "rescript/lib/es6/curry.js";
4+
5+
async function forEach(iterator, f) {
6+
var iteratorDone = false;
7+
while(!iteratorDone) {
8+
var match = await iterator.next();
9+
Curry._1(f, match.value);
10+
iteratorDone = match.done;
11+
};
12+
}
13+
14+
export {
15+
forEach ,
16+
}
17+
/* 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
@@ -57,3 +57,19 @@ let processMyAsyncIterator = async () => {
5757
*/
5858
@send
5959
external next: t<'a> => promise<value<'a>> = "next"
60+
61+
/**
62+
`forEach(iterator, fn)` consumes all values in the async iterator and runs the callback `fn` for each value.
63+
64+
See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
65+
66+
## Examples
67+
```rescript
68+
await someAsyncIterator->AsyncIterator.forEach(value => {
69+
if value > 10 {
70+
Console.log("More than 10!")
71+
}
72+
})
73+
```
74+
*/
75+
let forEach: (t<'a>, option<'a> => unit) => promise<unit>

src/Core__Iterator.mjs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,17 @@
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+
import * as Curry from "rescript/lib/es6/curry.js";
4+
5+
function forEach(iterator, f) {
6+
var iteratorDone = false;
7+
while(!iteratorDone) {
8+
var match = iterator.next();
9+
Curry._1(f, match.value);
10+
iteratorDone = match.done;
11+
};
12+
}
13+
14+
export {
15+
forEach ,
16+
}
17+
/* 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
@@ -78,3 +78,19 @@ Console.log(mapKeysAsArray) // Logs [7, 8] to the console.
7878
```
7979
*/
8080
external toArrayWithMapper: (t<'a>, 'a => 'b) => array<'b> = "Array.from"
81+
82+
/**
83+
`forEach(iterator, fn)` consumes all values in the iterator and runs the callback `fn` for each value.
84+
85+
See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN.
86+
87+
## Examples
88+
```rescript
89+
someIterator->Iterator.forEach(value => {
90+
if value > 10 {
91+
Console.log("More than 10!")
92+
}
93+
})
94+
```
95+
*/
96+
let forEach: (t<'a>, option<'a> => unit) => unit

test/ArrayTests.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ Test.run([
450450
Test.run([
451451
[
452452
"ArrayTests.res",
453-
109,
453+
112,
454454
20,
455455
39
456456
],
@@ -464,7 +464,7 @@ Test.run([
464464
Test.run([
465465
[
466466
"ArrayTests.res",
467-
110,
467+
113,
468468
20,
469469
34
470470
],

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: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
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 TestTests from "./TestTests.mjs";
56
import * as ArrayTests from "./ArrayTests.mjs";
67
import * as ErrorTests from "./ErrorTests.mjs";
78
import * as FloatTests from "./FloatTests.mjs";
89
import * as ObjectTests from "./ObjectTests.mjs";
910
import * as PromiseTest from "./PromiseTest.mjs";
1011
import * as ResultTests from "./ResultTests.mjs";
12+
import * as IteratorTests from "./IteratorTests.mjs";
1113
import * as TypedArrayTests from "./TypedArrayTests.mjs";
1214

1315
var bign = TestTests.bign;
@@ -64,7 +66,15 @@ var areSame = TypedArrayTests.areSame;
6466

6567
var o = TypedArrayTests.o;
6668

67-
var eq = FloatTests.eq;
69+
var eq = IteratorTests.eq;
70+
71+
var iterator = IteratorTests.iterator;
72+
73+
var syncResult = IteratorTests.syncResult;
74+
75+
var asyncIterator = IteratorTests.asyncIterator;
76+
77+
var asyncResult = IteratorTests.asyncResult;
6878

6979
export {
7080
bign ,
@@ -95,5 +105,9 @@ export {
95105
areSame ,
96106
o ,
97107
eq ,
108+
iterator ,
109+
syncResult ,
110+
asyncIterator ,
111+
asyncResult ,
98112
}
99113
/* IntTests Not a pure module */

test/TestSuite.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ include ObjectTests
77
include ResultTests
88
include TypedArrayTests
99
include FloatTests
10+
include DictTests
11+
include IteratorTests

0 commit comments

Comments
 (0)