You are here

The Iterator Pattern

Download the source for the Iterator Pattern or get it on Github.

Iterators allow us to traverse through all the elements of a collection, regardless of how that collection is implemented. With the Iterator pattern, we have a way to encapsulate looping through a collection or array of objects. It can also be handy if you want to loop through different types of objects in a collection all without exposing the internal structure. Let’s create our own just to see how it’s done.

First thing we need is our own iterator interface with our two most important functions, hasNext() and next(): hasNext() will be used to tell us if there is another object after the current one and next() will return that object. Here is our SampleIterator.interface.php:


interface SampleIterator  {
	public function hasNext();
	public function next();
}

We’ll flesh out our interface by defining the interface methods and adding a constructor that will populate an array to hold our collection of objects. If our position holder is at the last object or the next object is equal to NULL we’ll return false otherwise we have another object following the current one:


class ItemIterator implements SampleIterator  {
	private $_items = array();
	private $_position = 0;

	public function __construct($items)  {
		$count = 0;
		
		if(is_array($items))  {
			foreach($items as $obj)  {
				$this->_items[$count] = $obj;
				$count++;
			}
		}
	}

	public function hasNext()  {
		if($this->_position >= count($this->_items) || 
			$this->_items[$this->_position] == NULL)  {
				return false;
		} else  {
			return true;
		}
	}

	public function next()  {
		$item = $this->_items[$this->_position];
		$this->_position += 1;
		return $item;
	}
}

We can iterate over any object or data structure in this manner with very little code…

Our test file will pass an array of names but any object type could be used with the appropriate calls. Here is index.php:


function __autoload($class_name) {
	if(file_exists('classes/' . $class_name . '.class.php'))  {
		require_once 'classes/' . 
			$class_name . '.class.php';
	} elseif(file_exists('classes/' .
			$class_name . '.interface.php'))  {
		require_once 'classes/' . 
			$class_name . '.interface.php';
	}
}

$items = array('Andy','Bob','Cathy','Debbie','Eddie',
		'Frank','Gus','Heather','Ian','Janice',
		'Kim');
$itr = new ItemIterator($items);

while($itr->hasNext())  {
	$item = $itr->next();
	echo $item . '
'
; }

You should get something like:

Andy Bob Cathy Debbie Eddie Frank Gus Heather Ian Janice Kim

Many languages, including PHP, come fully loaded with predefined interfaces to handle iterators. Check out PHP5’s Iterator interface here and Java’s here.

Download the source for the Iterator Pattern or get it on Github.