イテレータ(Iterator)とジェネレータ(generator)

[up] [prev] [next]

目次

イテレータとは

イテレータ(iterator) は繰り返し処理を実現するための下記特徴を持つオブジェクトです。

イテラブルなオブジェクト(iterable object) は下記の特徴を持つオブジェクトです。

イテレータの実装例

下記に簡単なサンプルを用意してみました。MyRangeIterator がイテレータで、MyRange がイテラブルなオブジェクトです。

JavaScript
class MyRangeIterator {
  constructor(n, m) {
    this.n = n;
    this.m = m;
  }
  next() {
    return { value: this.n, done: this.n++ > this.m };
  }
}

class MyRange {
  constructor(n, m) {
    this.n = n;
    this.m = m;
  }
  [Symbol.iterator]() {
    return new MyRangeIterator(this.n, this.m);
  }
}

for (var n of new MyRange(1, 5)) {
  console.log(n);      // 1, 2, 3, 4, 5
}

下記の様にイテレータ自体をイテラブルなオブジェクトにすることもできます。

JavaScript
class MyRange {
  constructor(n, m) {
    this.n = n;
    this.m = m;
  }
  next() {
    return { value: this.n, done: this.n++ > this.m };
  }
  [Symbol.iterator]() {
    return this;
  }
}

for (var n of new MyRange(1, 5)) {
  console.log(n);          // => 1, 2, 3, 4, 5
}

ジェネレータとは

ジェネレータ(generator)はイテラブルなオブジェクトを簡単に生成できる仕組みです。

ジェネレータの実装例

ここでは myRange() というジェネレータ関数を定義しています。ジェネレータ関数はジェネレータを返却します。ジェネレータはイテレータでもあり、イテラブルなオブジェクトでもあるオブジェクトです。

JavaScript
function* myRange(n, m) {
  while (n <= m) {
    yield n++;
  }
}

for (var n of myRange(1, 5)) {
  console.log(n);          // => 1, 2, 3, 4, 5
}

yield * にイテラブルなオブジェクトを指定するとその値を順番に返却してくれます。下記の例では yield* でイテラブルなオブジェクトである Array() オブジェクトを指定しています。

JavaScript
function* myRange(n, m) {
  let array = new Array();
  for (let i = n; i <= m; i++) {
    array.push(i);
  }
  yield* array;
}

for (var n of myRange(1, 5)) {
  console.log(n);          // => 1, 2, 3, 4, 5
}

[up] [prev] [next]
Copyright (C) 2023 杜甫々
改訂版初版:2023年5月7日、最終更新:2023年5月7日
http://www.tohoho-web.com/js/itegen.htm