6
votes

Revêtement imbriqué avec une interface d'itérateur

foreach ($criteria as $key => $value) {
    $params[$key] = $value;
}

0 commentaires

3 Réponses :


2
votes

Eh bien, la seconde foreach va appeler $ itérator-> réinitialiser () code> avant d'exécuter. Ainsi, lorsque la deuxième forise atteint la fin de l'itérateur, le pointeur interne est déjà à la fin de la matrice ...

Ce serait comme: p> xxx pré>

Achetez le temps qu'il accède au $ it-> suivant () code> appel dans la boucle extérieure, c'est déjà invalide. Donc le suivant () code> appelle "échoue" et $ it--> valide () code> retournerait faux. P>

Ce n'est pas un problème avec les itérateurs , c'est un problème avec la logique que vous utilisez. Si vous devez vraiment nichez des boucles, alors clone code> l'itérateur ( $ subit = clone $ IT code>) dans la boucle interne afin de ne pas déranger le pointeur ... p>

EDIT: strong> Exemple avec clonage: p> xxx pré>

ou, à l'aide de pourcheche (qui est sémantiquement équivalent): P>

foreach ($it as $key => $value) {
    $subit = clone $it;
    foreach ($subit as $k => $v) {
        //Do stuff
    }
}


2 commentaires

Une alternative serait d'implémenter itératoragregate plutôt. Le clonage peut être une mémoire coûteuse si l'objet qui arrive à mettre en œuvre Itérateur encapsule beaucoup de données.


@ARTEFACTO Vous devriez écrire une réponse basée sur votre commentaire.



2
votes

J'ai essayé cela avec des tableaux simples et des itérateurs PHP. Malheureusement, des itérateurs PHP, puisqu'ils sont des objets, fonctionnent différemment. Les objets sont passés par référence pendant que les tableaux sont par rapport à la valeur. Ainsi, lorsque la nourriture imbriquée atteint la fin de l'itérateur, la première foreach ne peut pas reprendre là où elle s'est arrêtée car le pointeur interne est défini sur le dernier élément.

Considérez l'exemple suivant écrit à l'aide d'une matrice PHP uni: P>

first loop: 0
second loop: 0
second loop: 1
second loop: 2
first loop: 1
second loop: 0
second loop: 1
second loop: 2
first loop: 2
second loop: 0
second loop: 1
second loop: 2


0 commentaires

1
votes

EDIT: Après avoir posté cela, je me suis rendu compte que cela se brisera si vous faites Continuer code> ou BAISE CODE> dans le foreach imbriqué. Donc, ce n'est probablement pas votre solution souhaitée. Strong>

comme indiqué dans d'autres réponses PHP foreach appels rembobinet code> au début du foreach code> boucle code> valide code> à la fin de chaque itération. Donc, dans l'imbriquée foreach code> itérateur devient invalide et reste de cette façon dans le parent foreach code>. Voici une solution de contournement pirate qui utilise la pile de pointeurs au lieu d'un seul pointeur et que cet itérateur se comporte comme des tableaux dans ce cas. P> xxx pré>

sortie: p>

string(7) "loop1 A"
string(7) "loop2 A"
string(7) "loop2 B"
string(7) "loop2 C"
string(7) "loop1 B"
string(7) "loop2 A"
string(7) "loop2 B"
string(7) "loop2 C"
string(7) "loop1 C"
string(7) "loop2 A"
string(7) "loop2 B"
string(7) "loop2 C"


0 commentaires