PHP中是否有SPL反向数组迭代器?如果没有,最好的实现方式是什么?
我可以简单地执行以下操作:
$array = array_reverse($array);
foreach($array as $currentElement) {}
或者for($i = count($array) - 1; $i >= 0; $i--)
{
}
但是否有更优雅的方法?
PHP中是否有SPL反向数组迭代器?如果没有,最好的实现方式是什么?
我可以简单地执行以下操作:
$array = array_reverse($array);
foreach($array as $currentElement) {}
或者for($i = count($array) - 1; $i >= 0; $i--)
{
}
但是否有更优雅的方法?
这里是一个不复制也不修改数组的解决方案:
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));
没有ReverseArrayIterator
来实现这个功能。但是你可以这样做:
$reverted = new ArrayIterator(array_reverse($data));
或者将其转化为您自己的自定义迭代器,例如:
class ReverseArrayIterator extends ArrayIterator
{
public function __construct(array $array)
{
parent::__construct(array_reverse($array));
}
}
以下是稍微长一些的实现方式,它不使用 array_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);
}
}
在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 ...
}
这适用于数组和其他可迭代对象,而不必先复制它。
根据你要做的事情,你可能需要查看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
}
current()
来使其效率更高。for ($value = end($array); ($key = key($array)) !== null; $value = prev($array)) {
// ... do something with $key => $value
}
$array = array_reverse($array);
foreach($array as $key => $currentElement) {}
这是更好的使用方式。如果键不是连续或整数,它也会处理好。
foreach(array_reverse($array, true) ...
。请记住array_reverse
的第二个参数,它可以保留键。 - Charles$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);
}