Skip to content

Commit 270e25a

Browse files
committed
Use iterators and generators
1 parent f0ba673 commit 270e25a

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,90 @@ inventoryTracker('apples', req, 'www.inventory-awesome.io');
981981

982982
**[⬆ back to top](#table-of-contents)**
983983

984+
### Use iterators and generators
985+
986+
Use generators and iterables when working with collections of data used like a stream.
987+
There are some good reasons:
988+
- decouples the callee from the generator implementation in a sense that callee decides how many
989+
items to access
990+
- lazy execution, items are streamed on demand
991+
- built-in support for iterating items using the `for-of` syntax
992+
- iterables allow to implement optimized iterator patterns
993+
994+
For
995+
996+
**Bad:**
997+
998+
```ts
999+
function fibonacci(n: number): number[] {
1000+
if (n === 1) return [0];
1001+
if (n === 2) return [0, 1];
1002+
1003+
const items: number[] = [0, 1];
1004+
while (items.length < n) {
1005+
items.push(items[items.length - 2] + items[items.length - 1]);
1006+
}
1007+
1008+
return items;
1009+
}
1010+
1011+
function print(n: number) {
1012+
fibonacci(n).forEach(fib => console.log(fib));
1013+
}
1014+
1015+
// Print first 10 Fibonacci numbers.
1016+
print(10);
1017+
```
1018+
1019+
**Good:**
1020+
1021+
```ts
1022+
// Generates an infinite stream of Fibonacci numbers.
1023+
// The generator doesn't keep the array of all numbers.
1024+
function* fibonacci(): IterableIterator<number> {
1025+
let [a, b] = [0, 1];
1026+
1027+
while (true) {
1028+
yield a;
1029+
[a, b] = [b, a + b];
1030+
}
1031+
}
1032+
1033+
function print(n: number) {
1034+
let i = 0;
1035+
for (const fib in fibonacci()) {
1036+
if (i++ === n) break;
1037+
console.log(fib);
1038+
}
1039+
}
1040+
1041+
// Print first 10 Fibonacci numbers.
1042+
print(10);
1043+
```
1044+
1045+
There are libraries that allow working with iterables in a simillar way as with native arrays, by
1046+
chaining methods like `map`, `slice`, `forEach` etc. See [itiriri](https://www.npmjs.com/package/itiriri) for
1047+
an example of advanced manipulation with iterables (or [itiriri-async](https://www.npmjs.com/package/itiriri-async) for manipulation of async iterables).
1048+
1049+
```ts
1050+
import itiriri from 'itiriri';
1051+
1052+
function* fibonacci(): IterableIterator<number> {
1053+
let [a, b] = [0, 1];
1054+
1055+
while (true) {
1056+
yield a;
1057+
[a, b] = [b, a + b];
1058+
}
1059+
}
1060+
1061+
itiriri(fibonacci())
1062+
.take(10)
1063+
.forEach(fib => console.log(fib));
1064+
```
1065+
1066+
**[⬆ back to top](#table-of-contents)**
1067+
9841068
## Objects and Data Structures
9851069

9861070
### Use getters and setters

0 commit comments

Comments
 (0)