web-dev-qa-db-ja.com

PHP --SPLソリューションを使用して配列を逆に繰り返しますか?

PHPにSPL逆配列イテレータはありますか?そうでない場合、それを達成するための最良の方法は何でしょうか?

私は簡単に行うことができます

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

または

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

}

しかし、もっとエレガントな方法はありますか?

21
Sebastian Hoitz

それを行うためのReverseArrayIteratorはありません。できるよ

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

または、それを独自のカスタムイテレータにします。

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

配列をコピーおよび変更しないソリューションは次のとおりです。

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

現在のキーへの参照も必要な場合:

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

これは、php配列キーがnullになることはなく、ここに示されている他のどの回答よりも高速であるため、常に機能します。

45
linepogl
$item=end($array);
do {
...
} while ($item=prev($array));
14
AbiusX

何をしようとしているかによっては、SplStackなどのsplデータ構造クラスを調べたい場合があります。 SplStackはIterator、ArrayAccess、Countableを実装しているため、ほとんどの場合配列のように使用できますが、デフォルトでは、イテレーターはFILOの順序で進行します。例:

$stack = new SplStack();
$stack[] = 'one';
$stack[] = 'two';
$stack[] = 'three';

foreach ($stack as $item)
{
    print "$item\n";
}

これは印刷されます

three
two
one
9
rr.

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

これは、最初にコピーを作成しなくても、配列やその他の反復可能オブジェクトで機能します。

9
mpen

配列のキーを保持する場合は、2番目のパラメーターとしてtruearray_reverseに渡す必要があることに注意してください。

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

これは使用するためのより良い方法です。キーがシーケンシャルまたは整数でない場合は、キーも処理します。

4
Gaurav

linepogl's回答に基づく... current()呼び出しを回避することで、さらに効率的にすることができます。

for ($value = end($array); ($key = key($array)) !== null; $value = prev($array)) {
     // ... do something with $key => $value
}
2
C.M.
$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
}
1
Tadej Kobe

これは、新しい配列を構築しないため、よりパフォーマンスの高い方法になる可能性があります。また、空の配列も適切に処理します。

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