-
Notifications
You must be signed in to change notification settings - Fork 0
/
2.iterables.js
108 lines (91 loc) · 2.55 KB
/
2.iterables.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//
// Iterables
//
// iterables are objects that can be iterated over
const numbers = new Set([1, 2, 3, 4, 5]);
numbers;
let total = 0;
numbers.forEach(x => total += x);
total;
// wait, why do we need iterables when we have arrays?
// and why don't my array methods work?
// numbers.filter(x => x < 3); // .filter is not a function
// iterables are not guaranteed to exist in memory
// here's a generator that creates an iterable
function* generateNumbers() {
for (i = 1; i <= 5; i++) {
yield i;
}
}
const numbers2 = generateNumbers();
// they don't exist in memory
// ...we can't see them all at the same time
numbers2;
numbers2.next();
numbers2.next();
numbers2.next();
numbers2.next();
numbers2.next();
const x = numbers2.next();
x;
// but we can iterate over them
function getTotal(numbersIterable) {
let total = 0;
for (n of numbersIterable) {
total += n;
}
return total;
}
const result = getTotal(numbers2);
result;
// in order to view the contents we need to
// place them all in memory - using an array
const numbers3 = Array.from(generateNumbers());
numbers3;
// iterables can be exhausted
const numbers4 = generateNumbers();
const numbers4Total = getTotal(numbers4);
numbers4Total;
const numbers4TotalAgain = getTotal(numbers4);
numbers4TotalAgain;
// iterators allow us to fetch the next value on demand
const numbers5 = generateNumbers();
const a = numbers5.next();
a;
const b = numbers5.next();
b;
const c = numbers5.next();
c;
const d = numbers5.next();
d;
const e = numbers5.next();
e;
const f = numbers5.next();
f;
// it may be fair to say iterables can be treated
// like a synchronous stream
// how hard is it to implement our own generator?
function alphabetIterator() {
this._i = 65; // start at 'A'
this._x = 65 + 26; // end at 'X'
// 1. an iterator must have a next() method
// which returns { value: any, done: boolean }
this.next = () => {
if (this._i < this._x) {
return {
value: String.fromCharCode(this._i++),
done: false
};
}
return { done: true };
};
// 2. an iterator must have property a of Symbol.iterator
// which returns the a function to fetch its self
this[Symbol.iterator] = () => this;
}
const alphabet = new alphabetIterator();
const alphabetString = Array.from(alphabet).join("");
alphabetString;
// check out the iterator protocol:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterator_protocol
// protip: Look out for async iteratables in ES2018!