I need a queue where I add objects while working the queue (first in first out). In addition, I keep track of not having duplicate objects in a 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);
}
}
}
In PHP codepad, I don't get any result with this. What is wrong?
Update: After a while I get output:
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
I do dequeue and test for already done objects, why is this an infinite loop?
Line 25 is $test->enqueue($newObject);
For me, it's easier (and more natural, too) to work with SplQueue, using two basic methods only: enqueue to put an item at the end of the queue, and dequeue to extract the item you'll have to process from the beginning of the queue. This means getting rid of current, using the result of dequeue instead:
$current = $test->dequeue();
$done[$current] = 1;
var_dump($current); // or any other processing
As an attempt to dequeue an empty list causes an Error, you'll have to check for it first. So your code becomes similar to this:
$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;
}
}
}
Demo. As you see, there's another change here: setting a hash before doing enqueue. If you indeed want to make a HashQueue (of a sort), I'd suggest making your own class (extending or using SplQueue); the key would be accompanying each enqueue operation with the corresponding check/addition to hash.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With