1

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

我有一个 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;
    }
}
4

2 回答 2

4

您只需要实现RecursiveIterator接口。然后,您可以使用具体的RecursiveIteratorIterator对其进行迭代。

为了帮助你理解...

ARecursiveIterator本身并不是很“递归”。它只是提供了某些可用于获取孩子的方法(递归中的子问题可以被认为是“孩子”)。请注意,RecursiveIterator.getChildren() 必须以 another 的形式返回其子级RecursiveIterator

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

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

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

至于过滤——

有几种方法。为了便于使用,如果您有 php 5.4 ,我建议使用CallbackFilterIterator 。否则,您必须扩展FilterIterator

然而,在递归结构的,嗯,视图被扁平化为类似列表的结构之后,这两个过滤器都将元素过滤掉。因此,您的过滤器不能例如说“跳过整个子树”,它只能说“跳过这个单个元素”。如果您需要说“跳过整个子树”,则需要使用RecursiveCallbackFilterIterator或扩展RecursiveFilterIterator如果您没有 php 5.4

你可能想从

class RecursiveCategoryIterator implements RecursiveIterator {...

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

于 2012-06-08T21:32:26.177 回答
0

您必须从根节点开始并递归遍历每个$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)
于 2012-06-08T20:21:49.347 回答