今回は、「イテレータとジェネレーター」についてご紹介させて頂きます。
どちらもとても奥が深いので、ここでは本当に基本的な部分だけのご紹介となっています。
JavaScriptを学習中の方は、「for…of文」と合わせて学習されると理解が深まるかもしれません。
Itreable と Iterator
Itreable とは
Itreable(イテラブル)とは、配列等の集合したデータのことであり、値を一つずつ取り出すことが出来るもののことを言います。
Iterator とは
Iterator(イテレータ)とは、唯一の「next()」メソッドを持ち、反復子処理が出来るもののことを言います。
「next()」メソッドはメソッドを呼ぶたびに、イテレータから値が一つずつ返されます。
また、nextメソッドから得られるのは、「{value : 値, done : falseかtrue}」を持つオブジェクトになります。
使い方
[Symbol.iterator]() メソッド
let array = [1,2,3,4,5]; let iterator = array[Symbol.iterator]();
配列の数値を一つずつ取り出してみます。
「[Symbol.iterator]()」メソッドを使うことで、「Itreable」(ここでは配列)を取り出すことが出来ます。
let array = [1,2,3,4,5]; let iterator = array[Symbol.iterator](); console.log(iterator.next()); {value: 1, done: false} done: false value: 1 [[Prototype]]: Object
nextメソッドを使うことにより、valueとdoneが取得されています。
nextメソッドをもう一度使うと、次の値を取り出すことが出来ます。
console.log(iterator.next()); {value: 2, done: false} done: false value: 2 [[Prototype]]: Object
valueプロパティが2になりました。
doneプロパティはfalseのままです。
これは、doneプロパティが反復が終了したかどうかを判定しているためで、trueになれば反復は終了します。
console.log(iterator.next()); {value: 5, done: false} console.log(iterator.next()); {value: undefined, done: true}
ここでは、5回目まではvalueプロパティに値が表示されますが、6回目を実行すると、「{value: undefined, done: true}」と表示されます。
valueプロパティはundefinedとなり、doneプロパティはtrueとなったので、反復は終了します。
これ以上は何度実行しても、このオブジェクトが返されます。
values() メソッド
let array = [1,2,3,4,5]; let iterator = array.values(); console.log(iterator.next()); {value: 1, done: false}
「values() メソッド」を使っても同じ結果が返ります。
entries() メソッド
let fruits = ['バナナ', 'りんご', 'オレンジ', 'ぶどう']; let iterator = fruits.entries(); console.log(iterator.next()); {value: Array(2), done: false} done: false value: (2) [0, 'バナナ'] [[Prototype]]: Object console.log(iterator.next()); {value: Array(2), done: false} done: false value: (2) [1, 'りんご'] [[Prototype]]: Object
「entries() メソッド」を使うと、インデックスと値を取り出すことが出来ます。
keys() メソッド
let fruits = ['バナナ', 'りんご', 'オレンジ', 'ぶどう']; let iterator = fruits.keys(); console.log(iterator.next()); {value: 0, done: false}
「keys()メソッド」はインデックスのみ返します。
for…of 文
let iterator = [1,2,3,4,5]; for(let i of iterator.entries() ){ console.log(i); } (2) [0, 1] (2) [1, 2] (2) [2, 3] (2) [3, 4] (2) [4, 5]
以前学習した「for…of文」もイテレータに対応しています。
entriesメソッドを使って、インデックスと値を取り出しています。
let array = [1,2,3,4,5]; let iterator = array.values(); for(let i of array){ console.log(iterator.next()); } {value: 1, done: false} {value: 2, done: false} {value: 3, done: false} {value: 4, done: false} {value: 5, done: false}
valueプロパティとdoneプロパティを取得することも出来ます。
Generator
Generator(ジェネレーター)は、処理を抜け出したり、後から復帰出来る関数です。
とMDNでは説明されています。
何だか分かったような分からない説明です。
ジェネレーターを作成するには、「function*」を使います。
これが、「ジェネレーター関数」と呼ばれるものになります。
そして、returnの代わりに、「yield」を使います。
以下、例を見ていきましょう。
function* generator(){ yield 1; yield 2; yield 3; yield 4; yield 5; } for( let i of generator()){ console.log(i); } 1 2 3 4 5
「function* generator(){」でジェネレーター関数が呼ばれた時、コードが実行される前に、「ジェネレーターオブジェクト」が返されます。
ジェネレーターのメソッドは「next()」になります。
まず最初の「yield」を実行します。
ここではオブジェクトは、「value:1, done: false」です。
そして再び次の「yield」を実行します。
これを繰り返し、最後に「value: undefind, done: true」になったら処理は終了します。
この流れはイテレータの時を思い出してください。
function* generator(){ yield* [1,2,3,4,5]; } for( let i of generator()){ console.log(i);
なお、「yield」は「yield*」を使うとより簡単に書くことが出来ます。
あとがき
かなり簡単にご紹介させて頂きました。
ここでご紹介させて頂いた内容は本当に基本的な部分のみとなっています。
これからJavaScriptを使ってコードを書いていくうちに、さらに難しい書き方にも触れていくと思いますので、まずは基本をしっかりと身につけておきましょう。
なお、一部、日本語の解説が良くない部分があると思いますので、ぜひ色々なサイトを見て、理解を深めてください。
また、イテレータのメソッドは様々なものが追加されていきます。
実際に使用する機会があった時は、最新の情報を確認してください。
今回も最後までお読み頂きありがとうございました。