Question

Est-il possible de « regarder en avant » lors de l'itération d'un tableau en PHP 5.2 ?Par exemple, j'utilise souvent foreach pour manipuler les données d'un tableau :

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

Mais j'ai souvent besoin de jeter un coup d'œil à l'élément suivant en parcourant le tableau.Je sais que je pourrais utiliser un for boucle et référence l'élément suivant par son index ($array[$i+1]), mais cela ne fonctionnerait pas pour les tableaux associatifs.Existe-t-il une solution élégante à mon problème, impliquant peut-être SPL ?

Était-ce utile?

La solution

Vous pouvez utiliser le CachingIterator à cet effet.

Voici un exemple:

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

Le CachingIterator est toujours un pas derrière l'itérateur interne:

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

Ainsi, quand vous foreach sur $collection, l'élément courant de la ArrayIterator intérieure sera l'élément suivant déjà, vous permettant de jeter un regard dans ce:

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

Affichera:

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

Pour une raison quelconque, je ne peux pas expliquer, le CachingIterator essayera toujours de convertir l'élément courant en chaîne. Si vous souhaitez effectuer une itération sur une collection d'objets et doivent propriétés accéder à une des méthodes, passer CachingIterator::TOSTRING_USE_CURRENT comme deuxième au constructeur param.


Sur sidenote, le CachingIterator tire son nom de la capacité à mettre en cache tous les résultats qu'il a vus jusqu'à présent itératives. Pour que cela fonctionne, vous devez le instancier avec CachingIterator::FULL_CACHE et vous pouvez chercher les résultats mises en cache getCache().

Autres conseils

Utilisez array_keys.

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

Vous pouvez utiliser next et prev pour itérer un tableau. current renvoie la valeur des articles en cours et key la clé actuelle.

Alors vous pouvez faire quelque chose comme ceci:

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

    // …

    next($array);
}

Je sais que c'est un ancien poste, mais je peux expliquer cette chose en cours / suivant / prev mieux maintenant. Exemple:

$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

Je sais que je pourrais utiliser une boucle for et référencer l'élément suivant par son index ($array[$i+1]), mais cela ne fonctionnerait pas pour les tableaux associatifs.

Pensez à convertir votre tableau associatif en un tableau indexé séquentiellement avec tableau_valeurs(), vous permettant d'utiliser la solution simple pour la boucle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top