PHPにSPL逆配列イテレータはありますか?そうでない場合、それを達成するための最良の方法は何でしょうか?
私は簡単に行うことができます
$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配列キーがnullになることはなく、ここに示されている他のどの回答よりも高速であるため、常に機能します。
$item=end($array);
do {
...
} while ($item=prev($array));
何をしようとしているかによっては、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
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 ...
}
これは、最初にコピーを作成しなくても、配列やその他の反復可能オブジェクトで機能します。
配列のキーを保持する場合は、2番目のパラメーターとして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's回答に基づく... current()
呼び出しを回避することで、さらに効率的にすることができます。
for ($value = end($array); ($key = key($array)) !== null; $value = prev($array)) {
// ... do something with $key => $value
}
$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);
}