2009-07-23 8 views
5

Lorsque vous devez vérifier/avoir des combinaisons d'éléments de tableau, comment pouvez-vous éviter d'imbriquer foreach?combinaisons: éviter plusieurs foreach imbriquées

code Exemple:

$as = array($optionA1, $optionA2) 
$bs = array($optionB1, $optionB2) 
$cs = array($optionC1, $optionC2) 

foreach ($as as $a) { 
    foreach ($bs as $b) { 
     foreach ($cs as $c) { 
      $result = $this->method($a, $b, $c); 
      if ($result) etc 
     } 
    } 
} 

Toute personne ayant des approches alternatives permettant d'éviter la nidification?

+0

Pourquoi voulez-vous éviter l'imbrication? Ce que vous avez est déjà la solution la plus intuitive pour la plupart des problèmes. –

+1

Pour clarifier: Je voudrais éviter l'imbrication car il semble souvent très difficile à afficher bien codé ou propre. Je sais que ce n'est pas une raison pour l'abandonner, mais s'il y a une alternative plus soignée, j'aimerais en entendre parler. – koen

+1

Vous pouvez utiliser la récursivité au lieu de l'itération. Cela va déplacer l'imbrication de votre code dans le modèle objet. (Il est difficile d'être plus précis puisque votre exemple est si artificiel.) – bzlm

Répondre

7

Vous pouvez écrire votre propre classe Iterator qui implémente le Iterator interface. Vous pourriez alors faire en sorte que son constructeur accepte les trois tableaux et ensuite vous pouvez l'utiliser pour faire une boucle sur chaque combinaison avec foreach.

Cependant, je pense que ce serait beaucoup plus lent, donc je l'éviterais. Il serait intéressant de connaître les raisons pour lesquelles vous voulez éviter les boucles foreach imbriquées?

+0

Ce serait bien si quelqu'un qui m'avait voté ajouterait un commentaire –

+0

Tom Je n'ai pas voté bas mais je comment utiliser cette interface d'itérateur? Si vous me donnez un petit algorithme, ce sera utile! Merci! – Neocortex

+0

@BannedfromSO Pas vraiment sûr que c'était vraiment une bonne solution - trois boucles est probablement plus évident, donc je ne suis pas sûr que l'exemple en vaut la peine –

1

Avez-vous envisagé de prendre le nombre de chaque tableau et de les multiplier tous ensemble pour obtenir un nombre total de permutations, puis de forcer i à itérer ce nombre? Vous devriez faire une contre-manipulation amusante pour chaque tableau, mais cela devrait fonctionner.

1

Vous n'avez pas vraiment donné assez d'informations pour savoir quelle est l'alternative. Si vous voulez vraiment appeler method() avec toutes les combinaisons d'options de $ as, $ bs et $ cs, alors les boucles imbriquées feront ce qu'il faut. Est-ce que ce sont les boucles multiples imbriquées qui vous dérange, ou le fait que method() est appelée count ($ as) * count ($ bs) * count ($ cs) fois?

+0

Cette réponse ferait un excellent commentaire. :) – bzlm

+0

@bzlm: Je prétends ignorer! J'étais un SO n00b à l'époque! :) – Ether

2

Logiquement, vous devez parcourir chaque élément en quelque sorte. Vous êtes juste en train de mélanger le processus.

Si plusieurs boucles sont moche, vous devriez peut-être placer vos baies dans leurs propres classes, qui ont leurs propres 'contrôles' encapsulés.