How do I copy an ArrayIterator to preserve it's current iteration position?

假如想象 提交于 2019-12-06 08:59:37

问题


Because this seems like what I have to do to get this effect:

$arr = ['a'=>'first', 'b'=>'second', ...];
$iter = new ArrayIterator( $arr );

// Do a bunch of iterations...
$iter->next();
// ...

$new_iter = new ArrayIterator( $arr );
while( $new_iter->key() != $iter->key() ) {
    $new_iter->next();
}

Edit: Also, just to be clear, should I NOT be modifying the base array with unset()? I figure the array iterator stores its own copy of the base array, so using offsetUnset() doesn't seem right.


回答1:


ArrayIterator does not implement a tell() function, but you can emulate this, and then use seek() to go to the position you want. Here's an extended class that does just that:

<?php
    class ArrayIteratorTellable extends ArrayIterator {
        private $position = 0;

        public function next() {
            $this->position++;
            parent::next();
        }

        public function rewind() {
            $this->position = 0;
            parent::rewind();
        }

        public function seek($position) {
            $this->position = $position;
            parent::seek($position);
        }

        public function tell() {
            return $this->position;
        }

        public function copy() {
            $clone = clone $this;
            $clone->seek($this->tell());
            return $clone;
        }
    }
?>

Use:

<?php
    $arr = array('a' => 'first', 'b' => 'second', 'c' => 'third', 'd' => 'fourth');
    $iter = new ArrayIteratorTellable( $arr );

    $iter->next();

    $new_iter = new ArrayIteratorTellable( $arr );

    var_dump($iter->current()); //string(6) "second"
    var_dump($new_iter->current()); //string(6) "first"

    $new_iter->seek($iter->tell()); //Set the pointer to the same as $iter

    var_dump($new_iter->current()); //string(6) "second"
?>

DEMO


Alternately, you can use the custom copy() function to clone the object:

<?php
    $arr = array('a' => 'first', 'b' => 'second', 'c' => 'third', 'd' => 'fourth');
    $iter = new ArrayIteratorTellable( $arr );

    $iter->next();

    $new_iter = $iter->copy();

    var_dump($iter->current()); //string(6) "second"
    var_dump($new_iter->current()); //string(6) "second"
?>

DEMO




回答2:


The only solution I thought of is using a copy of current array

$arr = ['a'=>'first', 'b'=>'second'];
$iter = new ArrayIterator( $arr );
// Do a bunch of iterations...
$iter->next();
var_dump($iter->current());
// ...
$arr2 = $iter->getArrayCopy();
$new_iter = new ArrayIterator( $arr2 );

while( $new_iter->key() != $iter->key() ) {
    var_dump($new_iter->current());
    $new_iter->next();    
}


来源:https://stackoverflow.com/questions/20068602/how-do-i-copy-an-arrayiterator-to-preserve-its-current-iteration-position

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!