『プログラミングTypeScript』 第四章 - ジェネレーターとイテレーター
『プログラミングTypeScript』の第四章ではジェネレーターおよびイテレーターに関するセクションがある。そこではフィボナッチ数を生成するジェネレーターを返す関数 (ジェネレーター関数) が例示されている。
本記事では「素数を生成するジェネレーター」を返す関数を書いてみよう。素数は無限に存在するので、次の素数を返せるというのはジェネレーターの用途として適切だろう。
function *createPrimeGenerator() {
const primes = new Set<number>()
let current = 2
while (true) {
while (true) {
let isPrime = true
for (const prime of primes) {
if (current % prime === 0) {
isPrime = false
break
}
}
if (!isPrime) {
current++
continue
}
primes.add(current)
break
}
yield current++
}
}
const primeGenerator = createPrimeGenerator()
for (let i = 0; i < 100; i++) {
console.log(primeGenerator.next())
}
関数名の前に * をつけることでジェネレーター関数を定義できる。ジェネレーター関数はジェネレーター (Generator) を返し、その値は yield キーワードで生成される。利用者は next() をコールすることでジェネレーターに次の値を要求できる。
ジェネレーターとイテレーター
createPrimeGenerator() が返す値はジェネレーターだが、イテレーターでもある。もっと言えば、反復可能なイテレーターでもある。
『プログラミングTypeScript』から「反復可能オブジェクト」と「イテレーター」の定義を引用しよう。
反復可能オブジェクト:
Symbol.iteratorと呼ばれるプロパティを含んでいるオブジェクト。このプロパティの値は、イテレーターを返す関数。イテレーター:
nextと呼ばれるメソッドを定義しているオブジェクト。このnextメソッドはvalueおよびdoneというプロパティを持つオブジェクトを返す。
ここで IDE (IntelliJ IDEA) は先ほどの例での primeGenerator. の補完を次のように表示してくる。

System.iterator と next の両方を持つことがわかる。したがって、これは反復可能なイテレーターだと言える。
