追記:
後日 この記事を書いた時点でイテレーターパターンと連結リストを混同していた事がわかりました・・・
最初の様子を残しておきたいのでこのままにしておきます 笑
このコードを書いているときにイテレーターパターンというものがわかった(気がする)!
今回のコードは粒子系で、どうしても動かすオブジェクトの量が増えてしまう・・・
それを毎回for文で回すときにちょっと工夫しました。
イテレータパターンとは
このサイトがわかりやすい。 思い返してみたら前にもBox2dWebを使ってみる(2) - kkana's blogここで Box2Dワールドから物体の座標を取り出すときに使っていました。
配列みたいに順番にまとまってるものに対してindexを振らなくても良いのが利点。
データの構造を知らなくても個々の要素にアクセスできればよい、ので提供する情報も少なくて大丈夫そう。
hasNext()でまだ次の要素があればtrueを、なければfalseを返すメソッドを用意すると、
そのデータ個々に処理をかけたい気に、次があるならまだ続ける、なければ終了、とwhile文を使ってかける。
要素が増えてもindexをふり直さなくても良い!素晴らしい〜。
JavaScriptパターン ―優れたアプリケーションのための作法
- 作者: Stoyan Stefanov,豊福剛
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/02/16
- メディア: 大型本
- 購入: 22人 クリック: 907回
- この商品を含むブログ (77件) を見る
この本でいうと、7.3に出てきます。
また、ここのサイトも参考にしました。
教本(processing)ではどうしているのか
ArrayList<Particle> particles; void setup() { size(640,360); particles = new ArrayList<Particle>(); } void draw() { background(255); A new Particle object is added to the ArrayList every cycle through draw(). particles.add(new Particle(new PVector(width/2,50))); for (int i = 0; i < particles.size(); i++) { Particle p = particles.get(i); p.run(); } }
ArrayListというものがあるんですね・・。いいなぁ。
javascriptにもあるのかな、と思って探したけれどわかりませんでした。
実際書いたコード
ES6での書き方は(もうちょっと書きやすい方法があるかもしれませんが・・・)とりあえずcodepenに書いたので 、ES5の書き方をメモしておきます。
今回必要かな、と思って書いた機能は以下です。
- リストに要素を追加する
- 現在ポインタのさしている要素を返す
- 次の要素があるかどうか返す
- 次の要素を返す
- ポインタをはじめに戻す
//連結リストのクラス var LinkedList = function(){ //長さ this.length = 0; //ポインタの位置 this.index = 0; //データ this.data = []; } //挿入されたものを追加 LinkedList.prototype = { push : function(elm){ this.data.push(elm); this.length++; }, //現在の要素を返す current : function(){ return this.data[this.index]; }, //次があるか? hasNext : function(){ if(this.index < this.length){ return true; } else{ return false; } }, //次の要素を返す next : function(){ if(!this.hasNext()){ return false; } else{ this.index++; return this.data[this.index]; } }, //ポインタを先頭に戻す rewind : function(){ this.index = 0; } }
使うときは、こういう感じで
var list = new LinkedList(); for (var i = 0; i < 10; i++) { var p = i; list.push(p); } while (list.hasNext()) { console.log(list.current()); list.next(); } list.push('p'); list.rewind(); while (list.hasNext()) { console.log(list.current()); list.next(); }
教本の読んでいる章がついに複雑系に入ってきたので、たぶんこれからも出番があると思われる。
またいつものように書き直しながら使っていきたいな。
そして、イテレータで回している途中に、またイテレータで回したいとき
(個々のオブジェクトを操作してるときに、その操作の中でまた個々のオブジェクトを操作するときとか・・)
にポインタをみうしなって結局for文で書く事に・・。
なにかうまいやり方はないものか。
ES6にイテレーターパターンが最初からあるかも
と、ここまで書いて気がついたんですが ES6にはイテレーターパターン的なものが最初から用意されてるみたい。
十六章第二回 イテレータ — JavaScript初級者から中級者になろう — uhyohyo.net
全然わからなかったので、また後日しっかり読もう・・・。