它不是迭代器类的内置功能,但您仍然可以使用
RecursiveIteratorIterator
并建立一个堆栈,当你到达一片叶子时,你可以向后看一步。
以下是更多的PoC,它不是一个超级清洁的解决方案,但它是有效的,应该证明其原理:
实例
class MyIterator extends RecursiveIteratorIterator {
protected $stack = array();
protected $result = array();
public function __construct($data)
{
parent::__construct(new RecursiveArrayIterator($data), RecursiveIteratorIterator::SELF_FIRST);
}
public function getObjects()
{
foreach($this as $dummy);
return $this->result;
}
public function rewind()
{
parent::rewind();
$this->stack = array();
$this->result = array();
$this->pushIfNoLeaf();
}
public function next()
{
parent::next();
$this->pushIfNoLeaf();
}
public function beginIteration()
{
parent::beginIteration();
$this->popIfLeaf();
}
public function beginChildren()
{
parent::beginChildren();
$this->popIfLeaf();
}
protected function pushIfNoLeaf()
{
if ($this->getSubIterator()->hasChildren()) {
$this->stack[] = array('key' => $this->key(), 'value' => $this->current());
}
}
protected function popIfLeaf()
{
if (!$this->getSubIterator()->hasChildren()) {
$item = array_pop($this->stack);
$this->result[$item['key']] = $item['value'];
}
}
}
$data = array(
'obj1' => array(1,2,3),
'arr1' => array(
'obj2' => array(4,5,6),
'obj3' => array(7,8,9)
)
);
$iterator = new MyIterator($data);
var_dump($iterator->getObjects());
输出示例
array(3) {
["obj1"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["obj2"]=>
array(3) {
[0]=>
int(4)
[1]=>
int(5)
[2]=>
int(6)
}
["obj3"]=>
array(3) {
[0]=>
int(7)
[1]=>
int(8)
[2]=>
int(9)
}
}
DEMO