我很难让RecursiveFilterIterator
访问我不想接受的对象的子项,而不返回不可接受的对象。
我有两种类型的Node
对象:NodeTypeA
和NodeTypeA
,它们都扩展抽象类型Node
:
abstract class Node implements Countable, RecursiveIterator
{
protected $children;
public function __construct( array $children = array() )
{
$this->children = $children;
}
public function count()
{
return count( $this->children );
}
public function hasChildren()
{
if( !$this->valid() )
{
return false;
}
return count( $this->current() ) > 0;
}
public function getChildren()
{
return $this->current();
}
public function rewind()
{
reset( $this->children );
}
public function key()
{
return key( $this->children );
}
public function valid()
{
return null !== $this->key();
}
public function current()
{
return current( $this->children );
}
public function next()
{
next( $this->children );
}
}
class NodeTypeA extends Node {}
class NodeTypeB extends Node {}
...我为此定义了这个RecursiveFilterIterator
:
class RecursiveNodeFilterIterator
extends RecursiveFilterIterator
{
public function __construct( RecursiveIterator $iterator, $kind )
{
parent::__construct( $iterator );
$this->kind = $kind;
}
public function accept()
{
$current = $this->current();
return $this->hasChildren() || $current instanceof $this->kind;
}
public function getChildren()
{
return new self( $this->getInnerIterator()->getChildren(), $this->kind );
}
}
然后,当我运行此代码段时:
header( 'Content-Type: text/plain; charset=utf-8' );
$nodes = new NodeTypeA( array(
new NodeTypeB( array(
new NodeTypeA( array(
new NodeTypeB( array(
new NodeTypeA(),
new NodeTypeA()
) ),
) ),
new NodeTypeA( array(
new NodeTypeB( array(
new NodeTypeB( array(
new NodeTypeA(),
new NodeTypeB()
) ),
) )
) ),
new NodeTypeB()
) ),
new NodeTypeA()
) );
$rii = new RecursiveIteratorIterator(
new RecursiveNodeFilterIterator( $nodes, 'NodeTypeA' ),
RecursiveIteratorIterator::SELF_FIRST
);
foreach( $rii as $node )
{
echo str_repeat( ' ', $rii->getDepth() ) . get_class( $node ) . PHP_EOL;
}
我希望得到这个结果:
NodeTypeA
NodeTypeA
NodeTypeA
NodeTypeA
NodeTypeA
NodeTypeA
......但得到了:
NodeTypeB
NodeTypeA
NodeTypeB
NodeTypeA
NodeTypeA
NodeTypeA
NodeTypeB
NodeTypeB
NodeTypeA
NodeTypeA
换句话说,在迭代时,它还会在有子项时返回NodeTypeB
个对象。这是有道理的,因为在RecursiveNodeFilterIterator::accept()
我定义了return $this->hasChildren() || ...
,以便过滤器访问所有可能的子节点。
有没有办法让RecursiveNodeFilterIterator
访问NodeTypeB
的子节点而不实际返回NodeTypeB
个节点?
答案 0 :(得分:2)
一个简单的选择是使用过滤迭代器包装RecursiveIteratorIterator
,只有accept
个您感兴趣的项目。
(从评论移至回答)