在PHP 5.2中迭代数组时是否有可能“向前看”?例如,我经常使用foreach来操作数组中的数据:
foreach($array as $object) {
// do something
}
但是我经常需要在浏览数组时查看下一个元素。我知道我可以使用for
循环并通过它的索引($array[$i+1]
)引用下一个项目,但它不适用于关联数组。我的问题是否有任何优雅的解决方案,可能涉及SPL?
答案 0 :(得分:50)
您可以将CachingIterator用于此目的。
以下是一个例子:
$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
作为第二个参数传递给构造函数。
在旁注中,CachingIterator从缓存到目前为止迭代的所有结果的能力中获取它的名称。为此,您必须使用CachingIterator::FULL_CACHE
对其进行实例化,然后您可以使用getCache()
获取缓存的结果。
答案 1 :(得分:18)
使用array_keys
。
$keys = array_keys($array);
for ($i = 0; $i < count($keys); $i++) {
$cur = $array[$keys[$i]];
$next = $array[$keys[$i+1]];
}
答案 2 :(得分:7)
您可以使用next
和prev
来迭代数组。 current
返回当前项值,key
返回当前密钥。
所以你可以这样做:
while (key($array) !== null) {
next($array);
if (key($array) === null) {
// end of array
} else {
$nextItem = value($array);
}
prev($array);
// …
next($array);
}
答案 3 :(得分:3)
我知道这是一个老帖子,但我现在可以更好地解释当前/下一个/上一个事情。 示例:
$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
答案 4 :(得分:0)
我知道我可以使用for循环并通过索引引用下一个项目($ array [$ i + 1]),但它不适用于关联数组。
考虑将关联数组转换为带array_values()的顺序索引数组,允许您使用简单的for循环解决方案。
答案 5 :(得分:0)
旧帖子,但我付了两分钱:
如果您想向前看,您确实需要问自己“我是否以最好的方式解决了这个问题。”
您可以解决所有的超前问题,而无需进行超前工作。您只需要在集合之前声明一个“ $ prevItem”引用,并将其初始化为null。每次循环时,最后都要将$ prevItem设置为刚评估的当前数组项。实际上,您不必在高峰期开始工作,而是在第二项开始执行真正的逻辑,并使用$ prevItem引用进行操作。您会注意到$ prevItem为空,从而跳过了第一项。
$prevItem = null;
$prevKey = null;
foreach($collection as $key => $val)
{
if($prevItem != null)
{
//do your operation here
}
$prevItem = $val;
$prevKey = $key;
}
这是干净的代码,是一种通用模式。
在遍历基础数据结构时,不要四处乱动……这从来都不是一种好习惯,而且极少需要这样做。