Domanda

È possibile "sbirciare avanti" durante l'iterazione di un array in PHP 5.2?Ad esempio, utilizzo spesso foreach per manipolare i dati da un array:

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

Ma spesso ho bisogno di sbirciare l'elemento successivo mentre sfoglio l'array.So che potrei usare a for loop e fare riferimento all'elemento successivo tramite il suo indice ($array[$i+1]), ma non funzionerebbe per gli array associativi.Esiste una soluzione elegante per il mio problema, magari coinvolgendo SPL?

È stato utile?

Soluzione

È possibile utilizzare il CachingIterator per questo scopo.

Ecco un esempio:

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

Il CachingIterator è sempre un passo dietro l'iteratore interno:

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

In questo modo, quando si fa foreach sopra $collection, l'elemento corrente della ArrayIterator interna sarà l'elemento successivo già, che consente di sbirciare in esso:

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

output sarà:

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

Per qualche motivo non riesco a spiegare, il CachingIterator sarà sempre cercare di convertire l'elemento corrente a stringa. Se si desidera iterare su una collezione oggetto e la necessità di accedere alle proprietà un metodo, passare CachingIterator::TOSTRING_USE_CURRENT come secondo parametro al costruttore.


Su un sidenote, il CachingIterator prende il suo nome dalla capacità di memorizzare nella cache tutti i risultati che ha ripetuti su finora. Per questo lavoro, bisogna istanziare con CachingIterator::FULL_CACHE e quindi è possibile recuperare i risultati memorizzati nella cache con getCache().

Altri suggerimenti

Usa array_keys.

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

È possibile utilizzare next e prev per iterare un array. current restituisce il valore attuale e gli elementi key la chiave corrente.

Così si potrebbe fare qualcosa di simile:

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

    // …

    next($array);
}

So che questo è un vecchio post, ma posso spiegare che l'attuale prossima cosa / / prev meglio ora. Esempio:

$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

So che potrei usare un ciclo for e fare riferimento all'elemento successivo tramite il suo indice ($array[$i+1]), ma non funzionerebbe per gli array associativi.

Considera la possibilità di convertire il tuo array associativo in uno indicizzato sequenzialmente con valori_array(), consentendoti di utilizzare la semplice soluzione del ciclo for.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top