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

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

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

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

или

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

}

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

Ответы

Ответ 1

Для этого нет ReverseArrayIterator. Вы можете сделать

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

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

В зависимости от того, что вы пытаетесь сделать, вам может понадобиться изучить классы структуры данных 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

Ответ 5

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

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

Ответ 6

Основываясь на ответе 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 ...
}

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

Ответ 7

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

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

Ответ 8

$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
}

Ответ 9

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

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

Ответ 10

Основываясь на ответе linepogl... Вы можете сделать его еще более эффективным, избегая current() call

for ($value = end($array); ($key = key($array)) !== null; $value = prev($array)) {
     // ... do something with $key => $value
}

Ответ 11

$array1 = array (10,20,30,40,50);

        for($i = count($array1) - 1; $i >= 0; $i--)
        {
            $array2[]  = $array1[$i];

        }

        echo "<pre>";
            print_r($array2);
        echo "</pre>";