IteratorIterator 类

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

简介

此迭代器包装器允许将任何可遍历的转换为 Iterator。重要的是要理解,大多数不实现迭代器的类都有其原因,因为它们可能不支持完整的 Iterator 特性集。如果是这样,应该提供技术来防止误用,否则会遇到异常或致命错误。

类概要

class IteratorIterator implements OuterIterator {
/* 方法 */
public __construct(Traversable $iterator, ?string $class = null)
public current(): mixed
public key(): mixed
public next(): void
public rewind(): void
public valid(): bool
}

备注

注意:

此类允许通过 __call 魔术方法访问内部迭代器的方法。

目录

添加备注

用户贡献的备注 4 个备注

26
sven at rtbg dot de
9 年前
这个迭代器基本上只是一个围绕另一个迭代器的包装器。它不做任何花哨的事情,它只是将 rewind()、next()、valid()、current() 和 key() 的任何调用转发给内部迭代器。可以使用 getInnerIterator() 获取此内部迭代器。

一个特殊情况:当传递一个 IteratorAggregate 对象时,将调用该对象的 getIterator() 方法,并且将迭代该迭代器,并且在调用 getInnerIterator() 时也将返回该迭代器。

此类可以扩展,因此它是您自己的类的理想构建块,这些类只想修改一个或两个迭代器方法,而不是全部方法。

想要修剪 current() 方法返回的字符串吗?

<?php

class TrimIterator extends IteratorIterator
{
public function
current() {
return
trim(parent::current());
}
}

$innerIterator = new ArrayIterator(array('normal', ' trimmable '));

$trim = new TrimIterator($innerIterator);

foreach (
$trim as $key => $value) {
echo
"Key:\n";
var_dump($key);
echo
"Value:\n";
var_dump($value);
echo
"---next---";
}
?>

输出

Key
int(0)
Value
string(6) "normal"
---next---Key
int(1)
Value
string(9) "trimmable"
---next---
1
max-p at max-p dot me
8 年前
一个小小的提示,对于任何想要尽可能地模拟 foreach 的行为,以便使用相当挑剔的可遍历对象,而不使用 foreach。

- 在开始迭代之前,将调用 rewind()。
- 对于每次迭代,将在迭代器上调用以下方法
- valid()
- current()
- key()
- next()

这样说起来似乎很愚蠢,但在我的用例中,我需要将可遍历的数据库结果游标转换为过程式游标(hasNext + fetchArray)以实现向后兼容性,并且驱动程序要求每个函数按适当的顺序调用。
2
thomas at gielfeldt dot dk
7 年前
IteratorIterator::current() 不会调用内部迭代器的 current() 方法。

内部迭代器的 current() 方法在 rewind() 和 next() 上被调用(并缓存)。key() 和 valid() 也是如此。

示例
<?php

$i
= new ArrayIterator(range(1,10));
$i = new IteratorIterator($i);
iterator_to_array($i); // 寻求结束
print "Valid: " . $i->valid() . "\n";
$i->append('test');
print
"Valid: " . $i->valid() . "\n";
print
"Current: " . $i->current() . "\n";

?>

输出

Valid
Valid
Current


<?php

$i
= new ArrayIterator(range(1,10));
iterator_to_array($i); // 寻求结束
print "Valid: " . $i->valid() . "\n";
$i->append('test');
print
"Valid: " . $i->valid() . "\n";
print
"Current: " . $i->current() . "\n";
?>

输出

Valid
Valid: 1
Current: test

原因如上所述,IteratorIterator 调用 current()、key() 和 valid() 的方式。
2
wallacemaxters at gmail dot lcom
8 年前
另一个关于 IteratorIterator 效率的例子是一个小型类,用于枚举迭代器实现的迭代。

示例

<?php

class Enumerator extends IteratorIterator
{
/**
* 枚举器的初始值
* @param int
*/
protected $start = 0;

/**
* @param int
*/
protected $key = 0;

/**
* @param Traversable $iterator
* @param scalar $start
*/
public function __construct(Traversable $iterator, $start = 0)
{
parent::__construct($iterator);

$this->start = $start;

$this->key = $this->start;
}

public function
key()var_dump
{
return
$this->key;
}

public function
next()
{
++
$this->key;

parent::next();
}

public function
rewind()
{
$this->key = $this->start;

parent::rewind();
}

}
?>

这会生成

<?php

$enumerator
= new Enumerator(
new
ArrayIterator(['php', 'java', 'python']); 7000
);

print_r(iterator_to_array($enumerator));

/*
* array(3) {
7000 => 'php',
7001 => 'java',
7002 => 'python'
}
*/

?>
To Top