在PHP 5.2中,当使用foreach迭代数组时,是否可以“预览”数组的下一个元素?例如,我经常使用foreach来操作数组中的数据:
foreach($array as $object) {
// do something
}
我经常需要在遍历数组时查看下一个元素,我知道可以使用for
循环并通过索引引用下一个元素($array[$i+1]
),但这对关联数组不起作用。 是否有任何优雅的解决方案来解决我的问题,也许涉及SPL?
$collection = new CachingIterator(
new ArrayIterator(
array('Cat', 'Dog', 'Elephant', 'Tiger', 'Shark')));
CachingIterator 始终比内部迭代器慢一步:
var_dump( $collection->current() ); // null
var_dump( $collection->getInnerIterator()->current() ); // Cat
因此,当您通过foreach
遍历$collection
时,内部ArrayIterator的当前元素将是下一个元素,这使您能够窥视它:
foreach($collection as $animal) {
echo "Current: $animal";
if($collection->hasNext()) {
echo " - Next:" . $collection->getInnerIterator()->current();
}
echo PHP_EOL;
}
将输出:
Current: Cat - Next:Dog
Current: Dog - Next:Elephant
Current: Elephant - Next:Tiger
Current: Tiger - Next:Shark
Current: Shark
由于某种我无法解释的原因,CachingIterator将总是尝试将当前元素转换为字符串。如果您想迭代对象集合并需要访问属性和方法,请在构造函数的第二个参数中传递CachingIterator :: TOSTRING_USE_CURRENT。array_keys
函数。$keys = array_keys($array);
for ($i = 0; $i < count($keys); $i++) {
$cur = $array[$keys[$i]];
$next = $array[$keys[$i+1]];
}
next
和 prev
来迭代一个数组。 current
返回当前项的值,key
返回当前键名。while (key($array) !== null) {
next($array); // set pointer to next element
if (key($array) === null) {
// end of array
} else {
$nextItem = current($array);
}
prev($array); // resetting the pointer to the current element
// …
next($array);
}
我知道这是一篇旧文章,但现在我可以更好地解释当前/下一个/上一个的事情。例如:
$array = array(1,2,3,2,5);
foreach($array as $k => $v) {
// in foreach when looping the key() and current()
// is already pointing to the next record
// And now we can print current
print 'current key: '.$k.' and value: '.$v;
// if we have next we can print its information too (key+value)
if(current($array)) {
print ' - next key: '.key($array).' and value: '.current($array);
// at the end we must move pointer to next
next($array);
}
print '<br>';
}
// prints:
// current key: 0 and value: 1 - next key: 1 and value: 2
// current key: 1 and value: 2 - next key: 2 and value: 3
// current key: 2 and value: 3 - next key: 3 and value: 2
// current key: 3 and value: 2 - next key: 4 and value: 5
// current key: 4 and value: 5
虽然这是一篇旧帖,但我还是想发表我的看法:
如果你试图预先查看,你真的需要问自己“我是否以最佳方式解决了这个问题。”
你可以在不进行预先查看的情况下解决所有预先查看的问题。你只需要在集合之前声明一个"$prevItem"引用,并将其初始化为null。每次循环结束时,将$prevItem设置为刚刚评估过的当前数组项。实际上,你不是在预先查看,而是从第二个项目开始执行你的实际逻辑,并使用$prevItem引用来执行操作。通过注意到$prevItem为null,你跳过了第一个项目。
$prevItem = null;
$prevKey = null;
foreach($collection as $key => $val)
{
if($prevItem != null)
{
//do your operation here
}
$prevItem = $val;
$prevKey = $key;
}
这是干净的代码,也是一种常见的模式。
在迭代过程中避免对底层数据结构进行操作... 这不是好的实践方法,而且你很少需要这样做。
Catchable fatal error: Object of class MySampleClass could not be converted to string in /home/www/test.php on line 398
- pakoMySampleClass
中实现__toString
方法,要么在 CachingIterator 构造函数的第二个参数中传递CachingIterator::TOSTRING_USE_CURRENT
。 - Gordon