Мне нужна очередь, в которую я добавляю объекты во время работы с очередью (первым пришел — первым вышел).
Кроме того, я отслеживаю отсутствие дублирующих объектов в хэш-карте.
<?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);
Для меня проще (и более естественно, тоже) работать с 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
работа с соответствующей проверкой / дополнением к хешу.
Других решений пока нет …