• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • SplDoublyLinkedList::shift()

    (PHP 5 >= 5.3.0, PHP 7)

    Shifts a node from the beginning of the doubly linked list

    说明

    publicSplDoublyLinkedList::shift(void) : mixed

    参数

    此函数没有参数。

    返回值

    The value of the shifted node.

    错误/异常

    ThrowsRuntimeExceptionwhen the data-structure is empty.

    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.