gpt4 book ai didi

php - 在 PHP 中可以使用多个迭代器吗?

转载 作者:可可西里 更新时间:2023-10-31 22:16:48 26 4
gpt4 key购买 nike

也请检查 VolkerK 的答案,他提供了另一种解决方案,但我无法将两个帖子标记为答案。 :(


美好的一天!

我知道 C# 允许使用 yield 的多个迭代器,如下所述: Is Multiple Iterators is possible in c#?

在 PHP 中有 Iterator 接口(interface)。是否可以为一个类实现多个迭代场景?

更多细节(编辑):

例如,我有一个实现单个树节点的类 TreeNode。整棵树可以只用一个这个类来表示。我想提供迭代器来迭代当前节点的所有直接和间接子节点,例如使用 BreadthFirst 或 DepthFirst 顺序。

我可以将此 Iterators 实现为单独的类,但这样做我需要树节点将其子集合公开为公共(public)。

C#伪代码:

 public class TreeNode<T> 
{
...
public IEnumerable<T> DepthFirstEnumerator
{
get
{
// Some tree traversal using 'yield return'
}
}

public IEnumerable<T> BreadthFirstEnumerator
{
get
{
// Some tree traversal using 'yield return'
}
}
}

最佳答案

是的,你可以。

foreach(new IteratorOne($obj) as $foo) ....

foreach(new IteratorTwo($obj) as $bar) .....

实际上,只要您的类实现了 Iterator,您就可以对其应用任意 IteratorIterator。这是一件好事,因为应用的元迭代器不需要了解有关类的任何信息。

例如,考虑这样一个可迭代的类

class JustList implements Iterator
{
function __construct() { $this->items = func_get_args(); }
function rewind() { return reset($this->items); }
function current() { return current($this->items); }
function key() { return key($this->items); }
function next() { return next($this->items); }
function valid() { return key($this->items) !== null; }
}

让我们定义一些元迭代器

class OddIterator extends FilterIterator {
function accept() { return parent::current() % 2; }
}

class EvenIterator extends FilterIterator {
function accept() { return parent::current() % 2 == 0; }
}

现在将元迭代器应用于基类:

 $list = new JustList(1, 2, 3, 4, 5, 6, 7, 8, 9);

foreach(new OddIterator($list) as $p) echo $p; // prints 13579
foreach(new EvenIterator($list) as $p) echo $p; // prints 2468

更新:php 没有内部类,因此您在这里有点不走运,至少没有求助于 eval。您的迭代器需要是独立的类,它们知道基类结构。您可以通过在基类中提供在幕后实例化迭代器的方法来降低它的危害:

 class TreeDepthFirstIterator implements Iterator 
{
function __construct($someTree).....
}


class Tree
{
function depthFirst() { return new TreeDepthFirstIterator($this); }
....
}


foreach($myTree->depthFirst() as $node).....

另一种选择是使用 lambda 代替 foreach。这更好更灵活,但需要 php5.3:

 class Tree
{
function depthFirst($func) {
while($node = .....)
$func($node);

.....

$myTree->depthFirst(function($node) {
echo $node->name;
});

关于php - 在 PHP 中可以使用多个迭代器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2441969/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com