Uncovering Iterators

Post on 12-Jul-2015

961 views 2 download

Transcript of Uncovering Iterators

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!