Post on 12-Jul-2015
Uncovering Iterators
SJORS DE VALK25 NOVEMBER 2010
ITERATORS (1)
∂ Black magic?
ITERATORS (2)
∂ Holy grail?
ITERATORS (3)
“An iterator is an object that allows a programmer to traverse through all the elements of a collection.”
∂ Wikipedia
ITERATORS (4)
$i = array(1, 2, 3);reset($i);while (current($i) !== false) { echo key($values), current($values); next($values);}
∂ Array iteration (old school)
ITERATORS (5)
$i = new MyIterator();$i->rewind();while ($i->valid()) { echo $i->key(), $i->current(); $i->next();}
ITERATORS (6)
rewind() valid() key() current() next()
∂ As defined by the Iterator interface
ITERATORS (7)
$i = new MyIterator();foreach ($i as $key => $value) { echo $key, $value;}
∂ Methods are called automatically
BASICS (1)
$values = array( ‘Cameron Diaz’, ‘Alizée Jacotey’, ‘Britney Spears’, ‘Penélope Cruz’);
BASICS (2)
class NaiveWomenIterator implements Iterator { function __construct(array $values) {...} function rewind() {...} function valid() {...} function key() {...} function current() {...} function next() {...}}
BASICS (3)
class WomenIterator extends ArrayIterator { // Nothing here}
∂ Lean and mean
BASICS (4)
$i = new WomenIterator($values);$i = new WomenFilterIterator($i);foreach ($i as $name) { echo $name;}
BASICS (5)
class WomenFilterIterator extends FilterIterator { function accept() { return strpos($this->current(), ‘z’) !== false; }}
FIBONACCI (1)
Fibonacci sequence:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...
FIBONACCI (2)
$previous = 1;$current = 0;while (true) { echo $current; $oldCurrent = $current; $current += $previous; $previous = $oldCurrent;}
∂ Classic approach
FIBONACCI (3)
$i = new FibonacciIterator();foreach ($i as $value) { echo $value;}
∂ Iterator approach: hides the implementation
FIBONACCI (4)
$i = new FibonacciIterator();$i = new LimitIterator($i, 0, 50);foreach ($i as $value) { echo $value;}
∂ No need to change the original iterator
WORDS (1)
$contents = loadFile(‘http://www.gutenberg…’);$i = new NaiveWordIterator($contents);foreach ($i as $word) { echo $word;}
WORDS (2)
$contents = loadFile(‘http://www.gutenberg…’);$i = new CharacterIterator($contents);$i = new WordIterator($i);foreach ($i as $word) { echo $word;}
WORDS (3)
$contents = loadFile(‘http://www.gutenberg…’);$i = new CharacterIterator($contents);$i = new WordIterator($i);$i = new RegexIterator($i, ‘/god/i’);foreach ($i as $word) { echo $word;}
WORDS (4)
$contents = loadFile(‘http://www.gutenberg…’);$i = new CharacterIterator($contents);$i = new WordIterator($i);$i = new RegexIterator($i, ‘/god/i’);$i = new BigWordsFilterIterator($i, 5);foreach ($i as $word) { echo $word;}
WORDS (5)
$contents = loadFile(‘http://www.gutenberg…’);$i = new CharacterIterator($contents);$i = new WordIterator($i);$i = new WordFrequencyIterator($i);foreach ($i as $word) { echo $word;}
WORDS (6)
$contents = loadFile(‘http://www.gutenberg…’);$i = new CharacterIterator($contents);$i = new WordIterator($i);$i = new BigWordsFilterIterator($i, 10);$i = new WordFrequencyIterator($i);foreach ($i as $word) { echo $word;}
MP3 (1)
∂ Old school recursive directory iteration
function listFiles($path) { $files = array(); $handle = opendir($path); while (false !== ($file = readdir($handle))) { $files[] = $file; if (is_dir($path . ‘/’ . $file)) { $files = array_merge($files, listFiles($path . ‘/’ . $file)); } } return $files;}
MP3 (2)
∂ Lean and mean. Returns SplFileInfo
$i = new Mp3RecursiveDirectoryIterator($path);foreach ($i as $file) { echo $file->getFilename();}
MP3 (3)
$i = new Mp3RecursiveDirectoryIterator($path);
function render(Iterator $i) { echo $i->getDepth(), $i->getFilename(); return true;}
iterator_apply($i, ‘render’, array($i));
MP3 (4)
$i = new Mp3RecursiveDirectoryIterator($path);
echo count($i); // Nopeecho $i->count(); // Nopeecho iterator_count($i);
MP3 (5)
$i = new Mp3RecursiveDirectoryIterator($path);$i = new SongsIterator($i);
foreach ($i as $song) { echo $song->title;}
MP3 (6)
$i = new Mp3RecursiveDirectoryIterator($path);$i = new SongsIterator($i);
foreach ($i as $song) { foreach ($song as $property) { echo $property; // E.g. title, artist }}
MP3 (7)
∂ No need for a toArray()
class Song implements IteratorAggregate { function getIterator() { return new ArrayIterator( get_object_vars($this) ); }}
MP3 (8)
$i = new Mp3RecursiveDirectoryIterator($path);$i = new Mp3ShortSongsFilterIterator($i);
foreach ($i as $file) { echo $file->getFilename();}
MP3 (9)
$i = new Mp3RecursiveDirectoryIterator($path);$i = new Mp3ShortSongsFilterIterator($i);$i = new InfiniteIterator($i);
foreach ($i as $file) { echo $file->getFilename();}
MOVIES (1)
$i = new ImdbTopMoviesIterator();$i = new LimitIterator($i, 1, 10);
foreach ($i as $movie) { echo $movie->rank, $movie->title;}
MOVIES (2)
$i = new ImdbBoxOfficeMoviesIterator($url);$i = new LimitIterator($i, 1, 10);
foreach ($i as $movie) { echo $movie->rank, $movie->title;}
MOVIES (3)
$x = new ImdbTopMoviesIterator();$x = new LimitIterator($x, 1, 10);$y= new ImdbBoxOfficeMoviesIterator($url);$y = new LimitIterator($y, 1, 10);
$i = new MultipleIterator();$i->attachIterator($x);$i->attachIterator($y);
QUESTIONS?
∂ THANKS!