Если у меня есть класс, который реализует интерфейс Iterator
, я могу вручную контролировать, как итерация в цикле foreach
. Но существуют ли другие способы, с помощью которых мой объект может вести себя как массив?
Например, допустим, у меня есть Guestbook
класса, которая реализует Iterator
, так что я могу перебирать foreach (new Guestbook() as $entry)
. Но что, если я хочу, скажем, изменить порядок?
foreach (array_reverse(new Guestbook()) as $entry)
определенно не будет работать, потому что array_reverse
будет принимать только массив.
Я предполагаю, что я спрашиваю, могу ли я использовать Iterator
больше, чем просто петли foreach
?
Благодарю.
Цель интерфейса Iterator – разрешить использование вашего объекта в цикле foreach, он не предназначен для того, чтобы ваш объект действовал как массив. Если вы хотите что-то, что действует как массив, используйте массив.
Вы всегда можете превратить свой объект в массив с помощью функции iterator_to_array , но вы не можете отменить этот процесс.
Если вы видите необходимость изменения порядка элементов в своем итерируемом объекте, вы можете создать метод reverse (), который, возможно, использует array_reverse () внутри. Что-то вроде этого:-
class Test implements Iterator { private $testing = [0,1,2,3,4,5,6,7,8,9,10]; private $index = 0; public function current() { return $this->testing[$this->index]; } public function next() { $this->index ++; } public function key() { return $this->index; } public function valid() { return isset($this->testing[$this->key()]); } public function rewind() { $this->index = 0; } public function reverse() { $this->testing = array_reverse($this->testing); $this->rewind(); } } $tests = new Test(); var_dump(iterator_to_array($tests)); $tests->reverse(); var_dump(iterator_to_array($tests));
Вывод:-
array (size=11) 0 => int 0 1 => int 1 2 => int 2 3 => int 3 4 => int 4 5 => int 5 6 => int 6 7 => int 7 8 => int 8 9 => int 9 10 => int 10 array (size=11) 0 => int 10 1 => int 9 2 => int 8 3 => int 7 4 => int 6 5 => int 5 6 => int 4 7 => int 3 8 => int 2 9 => int 1 10 => int 0
Я написал код, чтобы доказать себе, что он будет работать до публикации, и подумал, что я мог бы также бросить его в ответ.
ArrayAccess
в свой класс.
См. Документацию здесь: http://www.php.net/arrayaccess
От PHP
Introduction Interface for external iterators or objects that can be iterated themselves internally.
Как видно из интерфейса Содержание ¶
Iterator::current — Return the current element Iterator::key — Return the key of the current element Iterator::next — Move forward to next element Iterator::rewind — Rewind the Iterator to the first element Iterator::valid — Checks if current position is valid
Операция предназначена для последующей итерации. Поэтому обратное, естественно, не работает и не предназначено для этого.
Для получения дополнительных интерфейсов, связанных с массивом, обратите внимание. ArrayAccess и счетный
Для решения на итераторе обратного объекта взгляните на ответ здесь. Итерации в обратном порядке через массив с помощью решения PHP – SPL?