Как скопировать ArrayIterator, чтобы сохранить текущую позицию итерации?

Потому что это похоже на то, что я должен сделать, чтобы получить этот эффект:

$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(); } 

Изменить: Также, чтобы быть ясным, не следует ли изменять базовый массив с помощью unset() ? Я полагаю, что итератор массива хранит свою собственную копию базового массива, поэтому использование offsetUnset() кажется неправильным.

ArrayIterator не реализует функцию tell() , но вы можете эмулировать это, а затем используйте seek() чтобы перейти в ArrayIterator позицию. Вот расширенный класс, который делает именно это:

 <?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; } } ?> 

Использование:

 <?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


В качестве альтернативы вы можете использовать пользовательскую функцию copy() для клонирования объекта:

 <?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

Единственное решение, о котором я думал, это использование копии текущего массива

 $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(); }