Итерации в обратном порядке через массив с PHP-SPL-решением?

Есть ли Итератор массива SPL Reverse в PHP? А если нет, то какой был бы лучший способ достичь этого?

Я мог бы просто сделать

$array = array_reverse($array); foreach($array as $currentElement) {} 

или

 for($i = count($array) - 1; $i >= 0; $i--) { } 

Но есть ли более элегантный способ?

Для этого не существует ReverseArrayIterator . Ты можешь сделать

 $reverted = new ArrayIterator(array_reverse($data)); 

или сделать это в свой собственный итератор, например

 class ReverseArrayIterator extends ArrayIterator { public function __construct(array $array) { parent::__construct(array_reverse($array)); } } 

Вот решение, которое не копирует и не изменяет массив:

 for (end($array); key($array)!==null; prev($array)){ $currentElement = current($array); // ... } 

Если вам также нужна ссылка на текущий ключ:

 for (end($array); ($currentKey=key($array))!==null; prev($array)){ $currentElement = current($array); // ... } 

Это работает всегда, поскольку ключи массива php никогда не могут быть нулевыми и быстрее, чем любой другой ответ, данный здесь.

 $item=end($array); do { ... } while ($item=prev($array)); 

В зависимости от того, что вы пытаетесь сделать, вам может понадобиться изучить классы структуры данных spl, например SplStack. SplStack реализует Iterator, ArrayAccess и Countable, поэтому его можно использовать в основном как массив, но по умолчанию его итератор работает в порядке FILO. Пример:

 $stack = new SplStack(); $stack[] = 'one'; $stack[] = 'two'; $stack[] = 'three'; foreach ($stack as $item) { print "$item\n"; } 

Это напечатает

 three two one 

Обратите внимание: если вы хотите сохранить ключи массива, вы должны передать true как второй параметр array_reverse :

 $array = array_reverse($array, true); foreach ($array as $currentElement) { // do something here } 
 $array = array_reverse($array); foreach($array as $key => $currentElement) {} 

Это лучший способ использования. Он также позаботится о ключах, если они не являются последовательными или целыми.

Основываясь на ответе linepogl , я придумал эту функцию:

 /** * Iterate an array or other foreach-able without making a copy of it. * * @param array|\Traversable $iterable * @return Generator */ function iter_reverse($iterable) { for (end($iterable); ($key=key($iterable))!==null; prev($iterable)){ yield $key => current($iterable); } } 

Применение:

 foreach(iter_reverse($my_array) as $key => $value) { // ... do things ... } 

Это работает с массивами и другими повторами без предварительного его копирования.

 $array=array( 0 => 0, '1' => 1, 2 => null, 3 => false ); $value=end( $array ); // ← value for first iteration while(($key=key( $array )) !== null) { echo "key=$key, value=$value\n"; $value=prev( $array ); // ← value for next iteration } 

Это может быть более результативным, поскольку он не создает новый массив. Он также хорошо обрабатывает пустые массивы.

 $item = end($items); while($item) { ...do stuff... $item = prev($items); } в $item = end($items); while($item) { ...do stuff... $item = prev($items); } 

$ array1 = массив (10,20,30,40,50);

  for($i = count($array1) - 1; $i >= 0; $i--) { $array2[] = $array1[$i]; } echo "<pre>"; print_r($array2); echo "</pre>";