Php 带SplQueue的无限循环
我需要一个队列,在该队列中我在处理队列时添加对象(先进先出)。 此外,我还跟踪hashmap中没有重复对象的情况Php 带SplQueue的无限循环,php,queue,spl,Php,Queue,Spl,我需要一个队列,在该队列中我在处理队列时添加对象(先进先出)。 此外,我还跟踪hashmap中没有重复对象的情况 <?php $test = new \SplQueue(); $done = array(); // Put 'test a' in queue $test->enqueue('test a'); // While we have objects in the queue... while ($test->valid()) { // Echo the
<?php
$test = new \SplQueue();
$done = array();
// Put 'test a' in queue
$test->enqueue('test a');
// While we have objects in the queue...
while ($test->valid()) {
// Echo the current object
$current = $test->current();
echo $current, PHP_EOL;
// Remove the current object and add it to "done"
$test->dequeue();
$done[$current] = 1;
// Add more to queue
$new = array('test a', 'test b', 'test c');
foreach ($new as $newObject) {
if (! isset($done[$newObject])) {
$test->enqueue($newObject);
}
}
}
我对已经完成的对象进行出列和测试,为什么这是一个无限循环
第25行是$test->enqueue($newObject)
对我来说,使用SplQueue更容易(也更自然),只使用两种基本方法:排队
将项目放在队列的末尾,以及出列
从队列的开头提取您必须处理的项目。这意味着使用出列
的结果来摆脱当前
:
$current = $test->dequeue();
$done[$current] = 1;
var_dump($current); // or any other processing
由于试图将空列表出列会导致错误,您必须首先检查它。因此,您的代码与此类似:
$test = new \SplQueue();
$done = array();
// Put 'test a' in queue
$test->enqueue('test a');
// While we have objects in the queue...
while (!$test->isEmpty()) {
$item = $test->dequeue();
$done[$item] = 1;
var_dump($item);
// Add more to queue
$new = array('test a', 'test b', 'test c');
foreach ($new as $newObject) {
if (! isset($done[$newObject])) {
$test->enqueue($newObject);
// without this line, `test c` will be enqueued twice.
$done[$newObject] = 1;
}
}
}
。如您所见,这里还有另一个变化:在执行
排队
之前设置哈希。如果您确实想创建一个HashQueue(某种类型),我建议您创建自己的类(扩展或使用SplQueue);该键将伴随每个将操作与相应的检查/添加到哈希一起排队。您必须提供正确的初始节点(使用$test->rewind()
,如中所示)。不得不说,我不太清楚为什么要这样使用SplQueue。使用Queue而不使用current
更自然;否则,您必须确保其当前节点确实是当前节点。如果您愿意的话,我会在回答中描述可能的方法。valid
方法到底做了什么?对我来说,它的行为不同于isEmpty
。所以我用错了SplQueue,你的方式确实更自然,谢谢!我已经在扩展SplQueue来跟踪处理过的对象;好主意。并不是为了让问题代码简单。
$test = new \SplQueue();
$done = array();
// Put 'test a' in queue
$test->enqueue('test a');
// While we have objects in the queue...
while (!$test->isEmpty()) {
$item = $test->dequeue();
$done[$item] = 1;
var_dump($item);
// Add more to queue
$new = array('test a', 'test b', 'test c');
foreach ($new as $newObject) {
if (! isset($done[$newObject])) {
$test->enqueue($newObject);
// without this line, `test c` will be enqueued twice.
$done[$newObject] = 1;
}
}
}