Espere adiante ao iterar uma matriz em PHP

É possível “peek ahead” enquanto itera um array em PHP 5.2? Por exemplo, muitas vezes uso foreach para manipular dados de uma matriz:

foreach($array as $object) { // do something } 

Mas muitas vezes eu preciso olhar para o próximo elemento ao passar pela matriz. Eu sei que eu poderia usar um loop for e referir o próximo item pelo seu índice ( $array[$i+1] ), mas isso não funcionaria para matrizes associativas. Existe alguma solução elegante para o meu problema, talvez envolvendo SPL?

Você pode usar o CachingIterator para este propósito.

Aqui está um exemplo:

 $collection = new CachingIterator( new ArrayIterator( array('Cat', 'Dog', 'Elephant', 'Tiger', 'Shark'))); 

O CachingIterator está sempre a um passo atrás do iterador interno:

 var_dump( $collection->current() ); // null var_dump( $collection->getInnerIterator()->current() ); // Cat 

Assim, quando você foreach mais de $collection , o elemento atual do ArrayIterator interno será o próximo elemento já, permitindo que você examine:

 foreach($collection as $animal) { echo "Current: $animal"; if($collection->hasNext()) { echo " - Next:" . $collection->getInnerIterator()->current(); } echo PHP_EOL; } 

Saída da saída:

 Current: Cat - Next:Dog Current: Dog - Next:Elephant Current: Elephant - Next:Tiger Current: Tiger - Next:Shark Current: Shark 

Por algum motivo, não posso explicar, o CachingIterator sempre tentará converter o elemento atual em string. Se você deseja iterar sobre uma coleção de objects e precisar acessar as propriedades de um método, passe o CachingIterator::TOSTRING_USE_CURRENT como o segundo parâmetro para o construtor.


Em um sidenote, o CachingIterator recebe o nome da capacidade de armazenar em cache todos os resultados que iterated até agora. Para que isso funcione, você precisa instanciá-lo com CachingIterator::FULL_CACHE e, em seguida, você pode obter os resultados em cache com o getCache() .

Use array_keys .

 $keys = array_keys($array); for ($i = 0; $i < count($keys); $i++) { $cur = $array[$keys[$i]]; $next = $array[$keys[$i+1]]; } 

Você pode usar o next e o prev para iterar uma matriz. current retorna o valor atual dos itens e key a chave atual.

Então você poderia fazer algo como isto:

 while (key($array) !== null) { next($array); if (key($array) === null) { // end of array } else { $nextItem = value($array); } prev($array); // … next($array); } 

Eu sei que esta é uma publicação antiga, mas posso explicar essa coisa atual / seguinte / anterior melhor agora. Exemplo:

 $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 '
'; } // 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

Eu sei que eu poderia usar um loop for e referir o próximo item pelo índice ($ array [$ i + 1]), mas isso não funcionaria para arrays associativos.

Considere converter sua matriz associativa em um índice indexado sequencialmente com array_values ​​() , permitindo que você use a solução simples for loop.