SplDoublyLinkedList::shift
(PHP 5 >= 5.3.0)
SplDoublyLinkedList::shift — Shifts a node from the beginning of the doubly linked list
Description
Parameters
This function has no parameters.
Return Values
The value of the shifted node.
Errors/Exceptions
Throws RuntimeException when the data-structure is empty.
- PHP Руководство
- Функции по категориям
- Индекс функций
- Справочник функций
- Другие базовые расширения
- Стандартная библиотека PHP (SPL)
- Структуры данных
- Функция SplDoublyLinkedList::add() - Add/insert a new value at the specified index
- Функция SplDoublyLinkedList::bottom() - Получает узел, находящийся в начале двусвязного списка
- Функция SplDoublyLinkedList::__construct() - Создает новый двусвязный список
- Функция SplDoublyLinkedList::count() - Подсчитывает количество элементов в двусвязном списке
- Функция SplDoublyLinkedList::current() - Возвращает текущий элемент массива
- Функция SplDoublyLinkedList::getIteratorMode() - Возвращает режим итерации
- Функция SplDoublyLinkedList::isEmpty() - Проверяет, является ли двусвязный список пустым
- Функция SplDoublyLinkedList::key() - Возвращает индекс текущего узла
- Функция SplDoublyLinkedList::next() - Перемещает итератор к следующему элементу
- Функция SplDoublyLinkedList::offsetExists() - Проверяет, существует ли запрашиваемый индекс
- Функция SplDoublyLinkedList::offsetGet() - Возвращает значение по указанному индексу
- Функция SplDoublyLinkedList::offsetSet() - Устанавливает значение по заданному индексу $index в $newval
- Функция SplDoublyLinkedList::offsetUnset() - Удаляет значение по указанному индексу $index
- Функция SplDoublyLinkedList::pop() - Удаляет (выталкивает) узел, находящийся в конце двусвязного списка
- Функция SplDoublyLinkedList::prev() - Перемещает итератор к предыдущему элементу
- Функция SplDoublyLinkedList::push() - Помещает элемент в конец двусвязного списка
- Функция SplDoublyLinkedList::rewind() - Возвращает итератор в начало
- Функция SplDoublyLinkedList::serialize() - Сериализует хранилище
- Функция SplDoublyLinkedList::setIteratorMode() - Устанавливает режим итерации
- Функция SplDoublyLinkedList::shift() - Удаляет узел, находящийся в начале двусвязного списка
- Функция SplDoublyLinkedList::top() - Получает узел, находящийся в конце двусвязного списка
- Функция SplDoublyLinkedList::unserialize() - Десериализует хранилище
- Функция SplDoublyLinkedList::unshift() - Вставляет элемент в начало двусвязного списка
- Функция SplDoublyLinkedList::valid() - Проверяет, содержит ли узлы двусвязный список
Коментарии
One may expect SplDoublyLinkedList::shift to properly maintain internal pointers, but this is not the case, this will yield no results, even if you rewind first
<?php
while ($splDoublyLinkedList->valid()) {
yield $splDoublyLinkedList->shift();
}
?>
It could be by design, but the following raises some more questions :
<?php
$test = new \SplDoublyLinkedList;
$dataSet = [
['id' => 1],
['id' => 2],
['id' => 3],
['id' => 4],
];
foreach ($dataSet as $row) {
$test->push($row);
}
echo "count: " . $test->count() . PHP_EOL;
echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo "current: " . var_export($test->current(), true) . PHP_EOL;
echo "key: " . $test->key() . PHP_EOL;
echo "1st shift: " . var_export($test->shift(), true) . PHP_EOL;
echo "count: " . $test->count() . PHP_EOL;
echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo "current: " . var_export($test->current(), true) . PHP_EOL;
echo "key: " . $test->key() . PHP_EOL;
echo "2nd shift: " . var_export($test->shift(), true) . PHP_EOL;
echo "count: " . $test->count() . PHP_EOL;
echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo "current: " . var_export($test->current(), true) . PHP_EOL;
echo "key: " . $test->key() . PHP_EOL;
echo "rewinding... " . PHP_EOL;
$test->rewind();
echo "current: " . var_export($test->current(), true) . PHP_EOL;
echo "2nd shift: " . var_export($test->shift(), true) . PHP_EOL;
echo "count: " . $test->count() . PHP_EOL;
echo "valid: " . ($test->valid() ? 'true' : 'false') . PHP_EOL;
echo "current: " . var_export($test->current(), true) . PHP_EOL;
echo "key: " . $test->key() . PHP_EOL;
?>
will result in :
<?php
/*
count: 4
valid: false <== First thing to note, you have no valid pointer unless you rewind first
current: NULL <== hence no current
key: 0 <== but we have a valid key
offsetGet(key): array ( <== indeed
'id' => 1,
)
1st shift: array ( <== and shift does return first row
'id' => 1,
)
count: 3 <== and count is maintained as expected
valid: false <== but internal pointer was left outside valid range
current: NULL <== hence no current again
key: 0 <== but we still have a valid key
offsetGet(key): array ( <== indeed
'id' => 2,
)
2nd shift: array ( <== and shift does return first row
'id' => 2,
)
count: 2 <== and count is maintained as expected
valid: false <== still not valid etc ..
current: NULL
key: 0
offsetGet(key): array (
'id' => 3,
)
rewinding... <== now rewind
current: array ( <== yay a current
'id' => 3,
)
3rd shift: array ( <== shift ok
'id' => 3,
)
count: 1 <== count ok
valid: true <== ouch valid
current: NULL <== with no current
key: 0 <== still our key is valid :o
offsetGet(key): array (
'id' => 4,
)
*/
?>
Conclusion : I may be missing something about why SplDoublyLinkedList::shift is not maintaining proper internal index in the first place, but I find it even more confusing to be able to end up with a valid valid() and a valid key() and no current() while there is obviously one.
Tested on php 5.6.30 & 7.1.2 with the exact same result.