gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

foreachとかiteratorとか

んと…まずiterator近辺は…多分、ないです。…見落としてるだけかもしれませぬが。
foreachは…二種類あります orz


まず。
いわゆる一般的な手続き型言語でのイメージとしてのforeach(PerlとかPHPとかJava(5.0+)とかC#とかDとかPython(for文だけどforeachと等価だよねぇ)とかVBとかcshとかsh系シェルとか)は…こんな感じ。

  //
  var awk:Array = ["a", "b", "c", 123];

  for each (var obj in awk) {
  	trace (obj.toString());
  }

まぁ当然といえば当然なのですが、objは「実値のcopy」なので。値を操作してもなんの意味もありません。

  //
  var awk:Array = ["a", "b", "c", 123];

  //
  for each (var obj in awk) {
  	trace (obj.toString());
  	obj = obj + " add";
  }
trace (awk.toString());

ついでに。似たような書式でfor in というのがあるのですが…これは「indexを返す」だけなので。ちょいと物足りない可能性があります。

  //
  var awk:Array = ["a", "b", "c", 123];

  //
  for (var obj in awk) {
  	trace (obj.toString());
  }


次に。「Arrayクラス(…以外にあるのかは不明。少なくともArrayクラスには、程度のニュアンスで捉えてください)にあるforEachというメソッド」という角度が存在します。
で、この子が………callback系の実装をしています。


サンプル1

とある関数 {
  //
  var awk:Array = ["a", "b", "c", 123];

  //
  awk.forEach(ff);
}

private function ff(item:*, index:int, array:Array):void
{
  trace("foreach start");
  trace(item.toString());
  trace(index.toString());
  trace(array.toString());
  trace("foreach end");
}


…少々微妙ではありますが(好みの問題ともいう…で、おいちゃん的にはまったく好みぢゃない)。
とりあえず、処理は可能。


で…疑問。
「foreach内で要素変更は可能か?」言い換えると「refererなのか実値のcopyなのか」。
結論「referer」。


で、サンプル2

とある関数 {
  //
  var awk:Array = ["a", "b", "c", 123];

  //
  awk.forEach(ff);
}

private function ff(item:*, index:int, array:Array):void
{
  //Alert.show("foreach start");
  //Alert.show(item.toString());
  //Alert.show(index.toString());
  //Alert.show(array.toString());
  //Alert.show("foreach end");

  trace("foreach start");
  trace(item.toString());
  trace(index.toString());
  trace(array.toString());
  trace("foreach end");
  array[index] = array[index] + " added";
  trace(item.toString());
  trace(array.toString());
  trace("foreach end");
}


次。callback関数に「クラスインスタンス+メソッド」は可能か?
答え。可能。

package
{
public class foo
{
  public function foo()
  {
  }

  public function f(item:*, index:int, array:Array):void
  {
    trace("foo foreach start");
    trace(item.toString());
    trace(index.toString());
    trace(array.toString());

    trace("foo foreach middle");

    array[index] = array[index] + " added";

    trace(item.toString());
    trace(array.toString());
    trace("foo foreach end");
  }
}
}
とある関数 {
  //
  var awk:Array = ["a", "b", "c", 123];

  //
  var f:foo = new foo;

  awk.forEach(f.f);
}


基本的なloopだってぇのに…まぁ盛りだくさん(苦笑
ただ…おいちゃん的には、iterator実装が欲しかったなぁ、とか思うのですが…どんなもんなんですかね?