需要迭代器建议来遍历树 [英] Need iterator advice to traverse tree

查看:119
本文介绍了需要迭代器建议来遍历树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我需要一些迭代器建议。

Hi I need some iterator advice.

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

I have a Category object which can contain a collection of items and also can have children categories.

从学说ORM我得到一个类别对象的集合。现在我想遍历这个集合并展平类别树结构。因此,子类别与其父级处于同一级别。我也想过滤孩子们。

From doctrine ORM I do get a collection of category objects. Now I want to traverse this collection and flatten the category tree structure. So the children categories are at the same level as it's parent. I would also like to filter the children.

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

Maybe somebody can point me in the right direction, currently a bit lost in the Iterator cloud.

<?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 界面。然后,您可以使用具体的 RecursiveIteratorIterator 进行迭代。

You simply need to implement the RecursiveIterator interface. Then, you can iterate over it using the concrete RecursiveIteratorIterator.

为了帮助您理解......

To help you understand...

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

A RecursiveIterator isn't very, um, "recursive" by itself. It is just something that offers up certain methods that can be used to get the children(the subproblem in recursion can be thought of as "children"). Notice that RecursiveIterator.getChildren() must return its children in the form of another RecursiveIterator.

您可以手动迭代一个普通的 RecursiveIterator ,但是,跟踪所有子项会非常痛苦通过递归调用 getChildren 返回的迭代器,并保持适当的深度等......那里有 RecursiveIteratorIterator 。 ..

You could manually iterate a plain RecursiveIterator, but, it would be pretty painful to keep track of all the sub iterators returned by the recursive calls to getChildren, and maintain the proper depth etc...thats where RecursiveIteratorIterator comes in...

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

A RecursiveIteratorIterator is the thing that does the actual work to systematically traverse the structure, mimicking recursion. It iterates through a RecursiveIterator as if it were a flat list, but at each element in the list, it tests the current element for the presence of children. If it hasChildren, it calls getChildren and stores the reference to this new child iterator in a Stack. It manages the Stack in a fashion that provides the recursive behavior you expect(much the same way you manually transform a recursive function into an iterative version).

要清楚,你不编码自己的 RecursiveIteratorIterator ,只是实例化php的具体实现。这个类纯粹是为了隐藏复杂性并管理所有在遍历过程中实例化的 RecursiveIterator 对象,并将遍历的结果呈现给你像一个单一的清单。 RecursiveIteratorIterator 内部是一个非常复杂的类。

To be clear, you don't code your own RecursiveIteratorIterator, just instantiate php's concrete implementation. This class exists purely to hide the complications and manage all the many RecursiveIterator objects that get instantiated in the traversal process from you, and presenting the result of the traversal to you as what seems like a flat list. RecursiveIteratorIterator is a very complicated class internally.

至于过滤 -

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

There's a few ways. For ease of use, I recommend to use CallbackFilterIterator if you have php 5.4. Otherwise, you must extend FilterIterator.

然而,在递归结构的视图已被展平为类似结构的列表之后,这两个元素都会过滤掉元素。所以,你的过滤器不能说例如跳过这整个子树,它只能说跳过这个单个元素。如果您需要说跳过整个子树,您需要使用 RecursiveCallbackFilterIterator 或者如果你没有php 5.4

However, both of those filter the elements out after the, um, view of the recursive structure has been flattened into a list like structure. So, your filter cannot for example say "skip this entire subtree", it can only say "skip this single element". If you need to say "skip this entire subtree" you need to use RecursiveCallbackFilterIterator or extend RecursiveFilterIterator if you dont have php 5.4

你可能想要开始

class RecursiveCategoryIterator implements RecursiveIterator {...

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

And that should contains a list of Category objects.

这篇关于需要迭代器建议来遍历树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆