【发布时间】:2011-07-12 16:29:55
【问题描述】:
考虑一个用于存储项目集合的对象,但该集合可能会因预定义的上下文而异。
Class Container implements IteratorAggregate (
protected $contexts; // list of associated contexts, example: array(0=>1,1=>3)
protected $contents; // array
public loadContents( $contextId ) { /* populates $this->contents*/ }
public getContexts() { /* populates $this->contexts */ }
...
public function getIterator() { return new ArrayIterator($this->contents); }
public getContextIterator() { return new contextIterator($this); }
}
迭代器看起来像:
Class contextIterator {
protected $container;
protected $contexts;
protected $currentContext;
public function __construct($container) {
$this->container = $container;
$this->contexts = $container->getContexts();
$this->currentContext = 0;
}
public current() {
$this->container->loadContents( $this->key() );
return $this->contexts[ $this->key() ];
}
public function key() { return $this->currentContext; }
public function next() { $this->currentContext++; }
public function rewind() { $this->currentContext = 0; }
public function valid() { return isset( $this->contexts[ $this->key() ] ); }
}
对于需要反复检查每个上下文的少数情况,我执行以下操作:
$myContainer = new Container();
foreach( $myContainer->getContextIterator() as $key => $value ) {
$myContainer->someMethod();
}
上面的代码很简洁,但我觉得很脏,因为我从来没有真正使用过 $key 或 $value。使用迭代器是否矫枉过正?此外,迭代器是否应该改变它正在迭代的对象的状态/内容?
【问题讨论】:
-
return $this->steps[ $this->key() ];-steps在哪里声明?有完整的代码会更容易回答。 -
哎呀,对不起。属性“步骤”应该是“上下文”。我编辑了我的问题。您还需要更多信息吗?
-
我真的不明白你在这里想要完成什么。这是你习惯用其他语言做的事情吗?我什至不得不问这个问题我觉得很愚蠢,因为我确信这里有更多经验丰富的程序员会为我的无知而抱怨。
-
嗯,所以 foreach 循环对我来说有点新,指向
$myContainer的指针在每次迭代中都会改变吗? -
@andho:$myContainer 是一个迭代器对象,因此对于每个“循环”,它的“当前”方法都被称为返回 $key 和 $value 的值。如果您对 foreach 不熟悉,请查看 foreach doc page。它非常适合遍历数组。但是,它也可以用于iterate over an object。