TD; LR;
JavascriptにもIteratorがありますよ、という話
Iterator
表で活躍するということは少ないかもしれませんが、Javascriptにもiteratorがあります
iteratorはなに?みたいになってしまった方は、こんな記事を読む前にGoFのiteratorパターンについて理解しておくのがいいかもしれませんが、この手の説明って全然わからないよね!!
https://ja.wikipedia.org/wiki/Iterator_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
いてれーしょん
実例みると早いかどうかはわらないが実例
const ary = [1,2,3,4,5]
const itr = ary[Symbol.iterator]()
itr.next() // {value: 1, done: false}
itr.next() // {value: 2, done: false}
itr.next() // {value: 3, done: false}
itr.next() // {value: 4, done: false}
itr.next() // {value: 5, done: false}
itr.next() // {value: undefined, done: true}
ary[Symbol.iterator]()
のところでiteratorを生成しています。Javascriptにおける「反復処理プロトコル」だそうです。かっこいいなMDN(ja)
繰り返し列挙しますということなんですが、普通はあんまり使わなくてすみます
本質はなにかっていえば
- 「列挙中に計算を止められる」
- 「止めた状態を保持できる」
- 「とりあえずnext()をすれば物がなんであれ統一的に次の値なりなんなりがもらえる」
つまり、ママンが
- 宿題やった?
- 教科書もった?
- お弁当もった?
っていうのを「忘れてた!」っていうたびに毎回最初から処理されたくないときにIteratorで途中の質問を保持してくれれば楽でいいですよね、ってことです(意味わからない)
(家でる直前で宿題やった→falseでもどうにもならんよなって、あとで思った)
Generator
配列とかはまだしも直感的なんですが、他になにに使用するの?
みたいなことを思う人もいると重います
普通にアプリとかつくってる人はあんまりないのです(validationがーとかの話ででてきたりするけど、だいたい実用性がない)
ただ疑似乱数生成みたいに「前の値を利用して次の値を生成する」的なやつ、
階差の漸化式とかで途中の計算結果を保持しつつ次の計算ができるようにする場合には便利です
Generatorのことです
事例はみんなだいすきフィボナッチ
function* fib_gen () {
let last_ = 0;
let now_ = 1;
let tmp = last_;
while(1){
yield now_;
tmp = last_
last_ = now_
now_ = now_ + tmp
}
}
const fib = fib_gen()
fib.next() // 1
fib.next() // 1
fib.next() // 2
fib.next() // 3
fib.next() // 5
fib.next() // 8
fibなんて無限に続く数列なんで計算すると途中でとめないといけないのだけど、generator実装するとベリーエレガントにいけます
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function*
function*はgeneratorをかえす処理を書くための特殊な定義なわけですが、結構書式あって面白かった
まとめ
Javascriptにはiteratorあるよ
感想
fib久しぶりに書いたしJavascriptのiteratorでもちゃんとかける。
あとこの話の派生はsetjmpとかcall/ccとかあるので、気になる方は「なんでも継続」でぐぐれ