SPL関数 ArrayIterator | 今日もWEB更新してたら

SPL関数 ArrayIterator

SPLをもう少し掘り下げてみようと思う。

ArrayIterator と ArrayObject

Javaで言うところの、ArrayList だ


ArrayObjectは、array() 関数で出来るArrayをもう少しObject志向にしたもんだ。


<?php
$array = array( "a", "b", "c" );
$current = current( $array );
?>



は全然オブジェクト指向っぽくない。

これをオブジェクト指向っぽいプログラミングスタイルにする


<?php
$array = array( "a", "b", "c" );
$array = new ArrayObject( $array );
$current = $array->getIterator()->current();
?>



これでオブジェクト指向っぽくなってきた。

ただ、コレではコードが増えただけで、何したいか分からない。



<?php
$array = new ArrayObject( $stdClass->propList() );
$cnt = $arra->count();
?>



もうすこしオブジェクト指向っぽくなった。

foreachに入れてやる。


<?php
$array = new ArrayObject( $stdClass->propList() );
foreach( $array as $value ){
  print( $value );
}
?>



わざわざWrapする必要があるのか?

あるんですよ。

たとえば、配列から奇数のIDだけを取り出すとき



<?php
$array = new ArrayObject( $stdClass->propList() );
foreach( $array as $key => $value ){
  if( ($key % 2) == 0 )continue;
  print( $value );
}
?>




こんなこと書いてたら見通しが悪い。(そう思って)

そんなときは、ArrayIteratorとArrayObjectの該当部分だけを書き換えてやる


<?php
class OddArrayIterator extends ArrayIterator{
 public function next(){
  if( parent::valid() ){
   parent::next();
  }
  if( parent::valid() == false ){
   return;
  }
  return parent::next();
 }
}
$array = array( "a", "b", "c" );
$array = new ArrayObject( $array , 0 , "OddArrayIterator" );
foreach( $array as $value ){
 print( $value );
}
?>


この実行結果は、


#takuya php> a c



となり、奇数だけが取得できる

こうやって適当に拡張していけばいい。

これでソースがスッキリして、見通しが良くなる。
とくにループの中で if や swtich を使って配列を探すときにはこのモデルを使えばスッキリする。

配列から特定の物だけを取り出しつつ配列を取得して処理していく。

GoFモデルでいう、IteratorとVisitorの組み合わせだ。


GoFモデルのようなパターンを簡単に扱えるからSPL関数は便利なのだろう。