Действительно ли возможно "посмотреть вперед" при итерации массива в PHP 5.2? Например, я часто использую foreach для управления данными из массива:
foreach($array as $object) {
// do something
}
Но я часто должен посмотреть на следующий элемент при прохождении через массива. Я знаю, что мог использовать a for
цикл и ссылка следующий объект он - индекс ($array[$i+1]
), но это не работало бы на ассоциативные массивы. Есть ли какое-либо изящное решение для моей проблемы, возможно, включая SPL?
Для этой цели можно использовать 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 ()
.
Используйте 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);
if (key($array) === null) {
// end of array
} else {
$nextItem = value($array);
}
prev($array);
// …
next($array);
}