过滤迭代器
利用迭代器
,你不仅仅可以显示集合中的每一项
。你还可以选择显示的项
。修改Library::getIterator()来使用其它两种迭代器类型。
classLibrary{
//...
functiongetIterator($type=false){
switch(strtolower($type)){
case‘media’:
$iterator_class=‘LibraryIterator’;
break;
case‘available’:
$iterator_class=‘LibraryAvailableIterator’;
break;
case‘released’:
$iterator_class=‘LibraryReleasedIterator’;
break;
default:
$iterator_class=‘LibraryGofIterator’;
}
returnnew$iterator_class($this->collection);
}
}
类LibraryAvailableIterator仅可以迭代状态为“library”的项”(重新调用checkOut()方法
,将状态更改为“borrowed”)。
classIteratorTestCaseextendsUnitTestCase{
//...
functionTestAvailableIteratorUsage(){
$this->lib->add($dvd=newMedia(‘test’,1999));
$this->lib->add(newMedia(‘name4’,1999));
$this->assertIsA(
$it=$this->lib->getIterator(‘available’)
,’LibraryAvailableIterator’);
$output=‘’;
while($item=$it->next()){
$output.=$item->name;
}
$this->assertEqual(‘name1name2name3testname4’,$output);
$dvd->checkOut(‘Jason’);
$it=$this->lib->getIterator(‘available’);
$output=‘’;
while($item=$it->next()){
$output.=$item->name;
}
$this->assertEqual(‘name1name2name3name4’,$output);
}
}
该测试创建一个新的介质实例,并将其存储在变量$dvd中。突出显示第一个assertEqual()声明验证利用LibraryAvailableIterator进行迭代时,存在一个新的项。接下来,测试使用checkOut()方法,并验证新的项已丢失,不显示。实现过滤得代码非常类似于LibraryIterator::next(),差别在于在返回项之前执行过滤。如果当前项与过滤条件不匹配,则代码返回$this->next()。
classLibraryAvailableIterator{
protected$collection=array();
protected$first=true;
function__construct($collection){
$this->collection=$collection;
}
functionnext(){
if($this->first){
$this->first=false;
$ret=current($this->collection);
}else{
$ret=next($this->collection);
}
if($ret&&‘library’!=$ret->status){
return$this->next();
}
return$ret;
}
}