PHPでlazy map
いまいち使いどころが見つからないけどPHPでlazy map書いてみた。
通常のmap(PHPだとarray_map)は、与えられたリストのすべてに関数を適用したリストを返すが、lazy mapでは実際にイテレータから値を取り出す時に初めて関数を適用する。
<?php class LazyMap implements Iterator { protected $iterator, $callback; function __construct($seq, $callback) { if (is_array($seq)) $this->iterator = new ArrayIterator($seq); elseif ($seq instanceof Iterator) $this->iterator = $seq; elseif ($seq instanceof IteratorAggregate) $this->iterator = $seq->getIterator(); else throw new InvalidArgumentException; if (!is_callable($callback)) throw new InvalidArgumentException; $this->callback = $callback; } function current() { return call_user_func($this->callback, $this->iterator->current()); } function next() { $this->iterator->next(); } function valid() { return $this->iterator->valid(); } function key() { return $this->iterator->key(); } function rewind() { $this->iterator->rewind(); } }
使ってみる
<?php function hoge($val) { echo "called\n"; return $val * $val; } $seq = array(1, 2, 3, 4, 5); // 通常のmap foreach (array_map('hoge', $seq) as $elt) { echo "{$elt}\n"; } echo "\n"; // lazy map foreach (new LazyMap($seq, 'hoge') as $elt) { echo "{$elt}\n"; }
結果
called called called called called 1 4 9 16 25 called 1 called 4 called 9 called 16 called 25
通常のmapが最初に全ての要素に関数を適用するのとは違い、lazy mapでは実際に値を取り出すまで関数の適用を遅延させていることが分かる。