使用PHP-SPL解决方案反向迭代数组?

使用PHP-SPL解决方案反向迭代数组?,php,reverse,loops,spl,Php,Reverse,Loops,Spl,PHP中是否有SPL反向数组迭代器? 如果没有,实现这一目标的最佳方式是什么 我可以这么做 $array = array_reverse($array); foreach($array as $currentElement) {} 或 但还有更优雅的方式吗 $item=end($array); do { ... } while ($item=prev($array)); 这是更好的使用方法。如果键不是连续的或整数的,它也会处理键。根据您尝试执行的操作,您可能需要查看spl数据结构类,例如Sp

PHP中是否有SPL反向数组迭代器? 如果没有,实现这一目标的最佳方式是什么

我可以这么做

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

但还有更优雅的方式吗

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

这是更好的使用方法。如果键不是连续的或整数的,它也会处理键。

根据您尝试执行的操作,您可能需要查看spl数据结构类,例如SplStack。SplStack实现了迭代器、ArrayAccess和Countable,因此它可以像数组一样使用,但默认情况下,它的迭代器按FILO顺序进行。例:

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

foreach ($stack as $item)
{
    print "$item\n";
}
这会打印出来

three
two
one

没有
reversearlayiterator
可以做到这一点。你能行

$reverted = new ArrayIterator(array_reverse($data));
或者将其转换为您自己的自定义迭代器,例如

class ReverseArrayIterator extends ArrayIterator 
{
    public function __construct(array $array)
    {
        parent::__construct(array_reverse($array));
    }
}
不使用
array\u reverse
而是通过标准数组函数迭代数组的稍长的实现是

class ReverseArrayIterator implements Iterator
{
    private $array;

    public function __construct(array $array)
    {
        $this->array = $array;
    }

    public function current()
    {
        return current($this->array);
    }

    public function next()
    {
        return prev($this->array);
    }

    public function key()
    {
        return key($this->array);
    }

    public function valid()
    {
        return key($this->array) !== null;
    }

    public function rewind()
    {
        end($this->array);
    }
}

请注意,如果要保留数组的键,必须将
true
作为第二个参数传递给
array\u reverse

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

这可能是一种性能更好的方法,因为它不构造新的数组。它还可以很好地处理空数组

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

以下是一个不复制也不修改阵列的解决方案:

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,并且比此处给出的任何其他答案都快。

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

$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
}
对于($i=count($array1)-1;$i>=0;$i--)
{
$array2[]=$array1[$i];
}
回声“;
印刷费($array2);
回声“;
基于此,我提出了以下功能:

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

for ($value = end($array); ($key = key($array)) !== null; $value = prev($array)) {
     // ... do something with $key => $value
}
这可以在阵列和其他iterables上运行,而无需先复制它。

根据linepogl的回答。。。通过避免调用
current()



你的第二种方法不一定正确。只适用于数字按键,没错。在我的例子中,我有一个数字数组,但你的评论使我的问题更加相关。数字数组不一定按顺序顺序排列,也不一定从0end开始设置内部数组迭代器到最后一个元素并返回它。prev返回当前元素并将迭代器设置为上一个元素。实际上,第二个版本将跳过数组的最后一个元素。向下投票。第二个版本跳过最后一个元素。如果数组的某个值为false、NULL或0怎么办?这可以缩短为仅
foreach(array\u reverse($array,true)…
如果不需要保留反转数组。请记住保留键的
array\u reverse
的第二个参数。如果其中一个项的值为false、NULL或0怎么办?我建议执行array\u reverse($array,true)为了保留数字键的键关联。请记住,array\u reverse会复制数组元素,因此性能不高。我不建议每次需要迭代时都这样做。最好从一开始就以相反的顺序存储内容,或者使用@linepogl的解决方案。不要优雅地反转整个数组哦,这个回复实际上并没有改变OP解决方案的任何内容,只是增加了语法上的糖分(甚至更多的开销)“弗朗西斯康姆”没有人要求一个优雅的解决方案。尽管它没有在程序方法上增加很多,但是OP专门要求一个SPL迭代器。没有解释的代码转储很少有帮助。请考虑在您的答案中添加一些上下文。这里最好的答案。谢谢!这是一个正确的遍历解决方案。数组,以相反顺序获取任何键(数字或非数字)和值(包括null)。不过OP要求使用迭代器。
        for($i = count($array1) - 1; $i >= 0; $i--)
        {
            $array2[]  = $array1[$i];

        }

        echo "<pre>";
            print_r($array2);
        echo "</pre>";
/**
 * 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 ...
}
for ($value = end($array); ($key = key($array)) !== null; $value = prev($array)) {
     // ... do something with $key => $value
}