Бесконечный цикл с SplQueue

Мне нужна очередь, в которую я добавляю объекты во время работы с очередью (первым пришел — первым вышел).
Кроме того, я отслеживаю отсутствие дублирующих объектов в хэш-карте.

<?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);
}
}
}

В коде PHP я не получаю никакого результата с этим.
Что случилось?

Обновление: Через некоторое время я получаю вывод:

test a
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /code/NIPg42 on line 25
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /code/NIPg42 on line 25

Я делаю dequeue и проверяю уже готовые объекты, почему это бесконечный цикл?

Строка 25 $test->enqueue($newObject);

3

Решение

Для меня проще (и более естественно, тоже) работать с SplQueue, используя два основных метода только: enqueue поместить элемент в конец очереди и dequeue чтобы извлечь элемент, который вам нужно обработать с начала очереди. Это значит избавиться от current, с использованием результат из dequeue вместо:

$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;
}
}
}

демонстрация. Как видите, здесь есть еще одно изменение: установка хеша перед выполнением enqueue, Если вы действительно хотите создать HashQueue (в некотором роде), я бы предложил создать свой собственный класс (расширение или использование SplQueue); ключ будет сопровождать каждого enqueue работа с соответствующей проверкой / дополнением к хешу.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]