您的位置:首页 > 其它

SPL学习笔记之二:迭代器

2015-05-18 16:31 363 查看
http://blog.csdn.net/cgh43/article/details/5884427

SPL迭代器接口的作用在于帮助实现高级的迭代算法,允许为类创建精巧的数据访问方法。

SPL提供了5个迭代器接口:Traversable、Iterator、IteratorAggregate、OuterIterator和RecursiveIterator。

1. Traversable:Traversable接口实际上不是一个接口,而更像是一个特性。这是因为只有内部的类(也就是用C语言编写的类)才可以直接实现Traversable接口。有两个派生自Traversable接口的基础级别的类,它们才是可以访问的接口,即Iterator接口和IteratorAggregate接口。

2. Iterator:允许一个类实现一个基本的迭代功能,从而使它可以被循环访问、根据键值来访问以及回滚。它实现了5个方法:rewind()、current()、key()、next()和valid()。

3. IteratorAggregate:用来将Iterator接口要求实现的5个迭代器方法委托给其它类,可以在类的外部实现迭代功能,并允许重新使用常用的迭代器方法。

IteratorAggregate接口当中包含一个getIterator()方法,实现此方法时,必须返回一个实现了Iterator接口的类的实例。通常在getIterator()方法内部,会把类的信息传递给一个特殊的迭代器类的构造函数。

IteratorAggregate接口使用范例:

[php]
view plaincopy

class MyIterableClass implements IteratorAggregate
{
protected $arr;

public function __construct()
{
$this->arr = array(1, 2, 3);
}

public function getIterator()
{
return new ArrayIterator($this->arr);
}
}

print_r(iterator_to_array(new MyIterableClass()));

4. OuterIterator:将一个或多个迭代器包裹在另外一个迭代器中。

OuterIterator接口定义如下:

[php]
view plaincopy

interface OuterIterator extends Iterator
{
function getInnerIterator();
}

OuterIterator接口与IteratorAggregate接口的区别在于它扩展了Iterator接口,扩展加入了一个getInnerIterator()方法。所有实现OuterIterator的类都必须实现Iterator接口定义的所有方法。getInnerIterator()方法应该返回当前正在迭代访问的迭代器。

OuterIterator接口形成了其它几个更加专用的迭代器的基础接口,其中包括AppendIterator、CachingIterator、FilterIterator、IteratorIterator、LimitIterator和RecursiveIteratorIterator接口。

5. RecursiveIterator:RecursiveIterator接口的作用在于提供了递归迭代访问的功能。

RecursiveIterator接口定义如下:

[php]
view plaincopy

interface RecursiveIterator extends Iterator
{
function hasChildren();
function getChildren();
}

SPL提供了多种迭代器,分别提供了迭代访问迭代器、过滤数据、缓存结果、控制分页等功能。

1. ArrayIterator:允许从PHP数组创建一个迭代器。

ArrayIterator迭代器使用范例:

[php]
view plaincopy

$arr = array('a', 'b', 'c');
$iterator = new ArrayIterator($arr);
foreach ($iterator as $val) {
echo $val;
}

当ArrayIterator迭代器和IteratorAggregate类一起使用时,免去了直接实现Iterator接口的方法的工作。

2. LimitIterator:返回给定数量的结果以及从集合中取出结果的起始索引点。LimitIterator迭代器实现了OuterIterator接口。

LimitIterator的构造函数接受3个参数:迭代器、偏移量和限制数量。

LimitIterator迭代器使用范例:

[php]
view plaincopy

$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
$arrIterator = new ArrayIterator($arr);
$iterator = new LimitIterator($arrIterator, 3, 4);
print_r(iterator_to_array($iterator));

这一迭代器适用于处理数据集的分页显示时。

3. AppendIterator:AppendIterator迭代器允许按顺序迭代访问几个不同的迭代器。在需要将来自于多个数据源的数据聚合到一个迭代器中时,这个迭代器非常有用。

以下代码范例创建一个包含每个输入数组前两个元素的数组

[php]
view plaincopy

$arrFirst = new ArrayIterator(array(1, 2, 3));
$arrSecond = new ArrayIterator(array(4, 5, 6));

$iterator = new AppendIterator();
$iterator->append(new LimitIterator($arrFirst, 0, 2));
$iterator->append(new LimitIterator($arrSecond, 0, 2));
print_r(iterator_to_array($iterator, false));

iterator_to_array()函数的第二个参数用于防止第一个迭代器中的数组键值被第二个迭代器覆盖。

4. FilterIterator:一个基于OuterIterator接口的迭代器,在迭代器中它被用来过滤数据,并且返回任何符合条件的元素。这个类有一个必须实现的抽象方法accept(),所以,FilterIterator类只能作为基类使用。accept()方法必须为迭代器中的当前项返回true或者false。

FilterIterator迭代器使用范例(筛选迭代器中值大于某个数值的元素):

[php]
view plaincopy

class GreaterThanThreeFilterIterator extends FilterIterator
{
private $filterVar;

public function __construct($iterator, $filterVar)
{
$this->filterVar = $filterVar;
parent::__construct($iterator);
}

public function accept()
{
return ($this->current() > $this->filterVar);
}
}

$arr = new ArrayIterator(array(1, 2, 4, 5, 7, 8, 9));
$iterator = new GreaterThanThreeFilterIterator($arr, 3);
print_r(iterator_to_array($iterator));

5. RegexIterator:RegexIterator是从FilterIterator类继承来的,它允许使用几种正则表达式模式来匹配和修改迭代器的数据集。

RegexIterator类的构造函数为:__construct($iterator, $regex, $op_mode=0, $spl_flags=0, $preg_flags=0);

RegexIterator迭代器使用范例(查找以字母a开头的所有项):

[php]
view plaincopy

$arr = array('apple', 'orange', 'avocado', 'pineapple');
$arrIterator = new ArrayIterator($arr);

$iterator = new RegexIterator($arrIterator, '/^a/');
print_r(iterator_to_array($iterator));

6. IteratorIterator:IteratorIterator是一种通用类型的迭代器,所有实现了Traversable接口的类都可以被它迭代访问。

某些PHP扩展中有些类没有实现Iterator接口或者IteratorAggregate接口,却实现了Traversable接口,IteratorIterator就适用于这种情况。

IteratorIterator迭代器使用范例(使用IteratorIterator迭代器和LimitIterator迭代器来限制结果集):

[php]
view plaincopy

$db = new PDO('xxxx');
$pdoStatement = $db->query('SELECT * FROM table');

$iterator = new IteratorIterator($pdoStatement);
$limitIterator = new LimitIterator($iterator, 0, 10);
$tenRecordArray = iterator_to_array($limitIterator);

7. CachingIterator:CachingIterator迭代器用来执行提前读取一个元素的迭代操作。

8. SeekableIterator:SeekableIterator迭代器可用于创建非顺序访问的迭代器。它允许跳转到迭代器中的任何一点上,而不用迭代访问所有这一点之前的元素。

9. NoRewindIterator:NoRewindIterator迭代器可用于不能回卷的集合,或者说是不能多次迭代的集合。当需要在迭代过程中执行一次性操作时,这种迭代器非常有用。

10. EmptyIterator:EmptyIterator是一种占位符形式的迭代器,它不执行任何操作。当要实现某个抽象类的方法并且这个方法需要返回一个迭代器时,可以使用这一迭代器。它也可以用于执行迭代器之间的比较操作。

11. InfiniteIterator:InfiniteIterator迭代器用来持续地循环访问数据。当迭代操作找到最后一个元素时,迭代器会回卷,并再次从第一个元素开始迭代访问数据。

12. RecursiveArrayIterator:RecursiveArrayIterator迭代器允许创建一个用于递归形式数组结构的迭代器。它为许多更复杂的迭代器提供了所需的操作,如RecursiveTreeIterator迭代器和RecursiveIteratorIterator迭代器。

13. RecursiveIteratorIterator:RecursiveIteratorIterator迭代器允许获得一个树形结构,并将它展开为一维结构。当这个迭代器发现一个子迭代器时,它会迭代访问这一子迭代器。

14. ParentIterator:ParentIterator是一个扩展的FilterIterator迭代器,它可以过滤掉来自于RecursiveIterator迭代器的非父元素,从而只找出拥有子元素的的键值。

ParentIterator迭代器使用范例:

[php]
view plaincopy

$arr = array('a', array('a', 'b', 'c'), 'b', array('d', 'e'), 'c');
$arrayIterator = new RecursiveArrayIterator($arr);
$iterator = new ParentIterator($arrayIterator);
print_r(iterator_to_array($iterator, false));

15. RecursiveFilterIterator:RecursiveFilterIterator迭代器是FilterIterator迭代器的递归形式。它也要求实现抽象的accept()方法,但是在这个方法中,应该使用$this->getInnerIterator()方法访问当前正在迭代的迭代器。

16. RecursiveRegexIterator:RecursiveRegexIterator迭代器是RegexIterator迭代器的递归形式,与RegexIterator不同的是它只接受RecursiveIterator迭代器作为迭代的对象。

17. RecursiveCachingIterator:RecursiveCachingIterator迭代器在RecursiveIterator迭代器上执行提前读取一个元素的递归操作。在确定当前迭代的项是叶子还是节点时,它非常有用。

18. SearchIterator:SearchIterator迭代器同时执行了过滤和限制操作,在找到一个匹配的元素之后它会停止操作。它是一个抽象类,和其它FilterIterator迭代器一样,必须实现accept()方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: