需要迭代器建议来遍历树


Need iterator advice to traverse tree

嗨,我需要一些迭代器建议。

我有一个 Category 对象,它可以包含项目的集合,也可以有子类别。

从教义ORM中,我确实得到了类别对象的集合。现在我想遍历这个集合并扁平化类别树结构。因此,子类别与其父类别处于同一级别。我还想过滤一下孩子。

也许有人可以指出我正确的方向,目前在迭代器云中有点迷失。

<?php
class Category
{
    private $name;
    private $children;
    private $type;
    private $parent;
    private $items;
    //parent category
    public function getParent()
    {
        return $this->parent;
    }
    public function setItems($items)
    {
        $this->items = $items;
    }

    public function getItems()
    {
        return $this->items;
    }
    //colelction of categories
    public function getChildren()
    {
        return $this->children;
    }
}

你只需要实现递归迭代器接口。然后,您可以使用具体的递归迭代器迭代它。

为了帮助您了解...

RecursiveIterator本身并不是非常"递归"。它只是提供了某些可用于获取子项的方法(递归中的子问题可以被认为是"子问题")。请注意,RecursiveIterator.getChildren () 必须以另一个RecursiveIterator的形式返回其子项。

您可以手动迭代一个普通RecursiveIterator,但是,跟踪递归调用返回的所有子迭代器getChildren,并保持适当的深度等,这将是非常痛苦的......这就是RecursiveIteratorIterator的用武之地...

RecursiveIteratorIterator是执行实际工作以系统地遍历结构,模仿递归的东西。它像平面列表一样循环访问RecursiveIterator,但在列表中的每个元素上,它会测试当前元素是否存在子元素。如果它hasChildren,它将调用getChildren并将对这个新子迭代器的引用存储在堆栈中。它以提供您期望的递归行为的方式管理 Stack(与手动将递归函数转换为迭代版本的方式非常相似)。

需要明确的是,你不需要编写自己的RecursiveIteratorIterator,只是实例化php的具体实现。此类的存在纯粹是为了隐藏复杂性并管理遍历过程中实例化的所有许多RecursiveIterator对象,并将遍历的结果呈现给您,看起来像是一个平面列表。 RecursiveIteratorIterator内部是一个非常复杂的类。

至于过滤——

有几种方法。为了便于使用,如果你有 php 5.4,我建议使用 CallbackFilterIterator。否则,必须扩展筛选器迭代器。

但是,在递归结构的视图被展平为类似列表的结构之后,这两个方法都会过滤掉元素。因此,您的过滤器不能说"跳过整个子树",它只能说"跳过这个单一元素"。如果你需要说"跳过整个子树",你需要使用RecursiveCallbackFilterIterator,或者如果你没有php 5.4,则扩展RecursiveFilterIterator

您可能想从

class RecursiveCategoryIterator implements RecursiveIterator {...

这应该包含一个类别对象列表。

您必须从根节点开始,递归遍历每个$this->getChildren()(节点和子节点(及其子节点(及其子节点(及其子节点))(递归),直到null。 这将导致如下所示的内容:

(Start)
Root node
-> 1st Child node
--> Grandchild node
-> 2nd Child node
-> 3rd Child node
-> 4th Child node
--> Grandhild node
(No more children so exit)