Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 带SplQueue的无限循环_Php_Queue_Spl - Fatal编程技术网

Php 带SplQueue的无限循环

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

我需要一个队列,在该队列中我在处理队列时添加对象(先进先出)。 此外,我还跟踪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 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; 
        }
    }
}