2009-07-23 15 views
5

Wenn Sie überprüfen müssen/haben Kombinationen von Array-Elementen, wie können Sie vermeiden, fexEach nesting?Kombinationen: Vermeiden mehrerer verschachtelter foreach

Beispielcode:

$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 
     } 
    } 
} 

Wer mit alternativen Ansätzen, die Verschachtelung vermeiden können?

+0

Warum möchten Sie die Verschachtelung vermeiden? Was Sie haben, ist bereits die intuitivste Lösung für die meisten Probleme. –

+1

Zur Verdeutlichung: Ich möchte die Verschachtelung vermeiden, da es oft sehr schwierig wird, gut codiert oder sauber darzustellen. Ich weiß, das ist kein Grund, es aufzugeben, aber wenn es eine schönere Alternative gibt, würde ich gerne davon hören. – koen

+1

Sie könnten Rekursion anstelle von Iteration verwenden. Dadurch wird die Verschachtelung von Ihrem Code in das Objektmodell verschoben. (Es ist schwierig, genauer zu sein, da Ihr Beispiel so erfunden ist.) – bzlm

Antwort

7

Sie könnten Ihre eigene Iterator-Klasse schreiben, die die Iterator interface implementiert. Sie könnten dann den Konstruktor die drei Arrays akzeptieren lassen und sie dann verwenden, um jede Kombination mit foreach zu durchlaufen.

Aber ich denke, das wäre deutlich langsamer, also würde ich es vermeiden. Es wäre interessant zu wissen, warum Sie die verschachtelten foreach-Schleifen vermeiden wollen.

+0

Es wäre nett, wenn jemand, der mich herabstimmte, einen Kommentar hinzufügen würde –

+0

Tom Ich habe Sie nicht abgelehnt, aber ich habe die Iterator-Schnittstelle benutzt? Wenn Sie mir einen kleinen Algorithmus geben, wird es nützlich sein! Vielen Dank! – Neocortex

+0

@BannedfromSO Nicht wirklich sicher, das war wirklich eine gute Lösung - drei Schleifen ist wahrscheinlich mehr offensichtlich, so bin ich mir nicht sicher, ob das Beispiel lohnend ist –

1

Haben Sie darüber nachgedacht, die Anzahl der einzelnen Arrays zu berechnen und sie alle zu multiplizieren, um eine Gesamtzahl von Permutationen zu erhalten, und dann eine i-Anweisung auszuführen, um diese Anzahl zu iterieren? Sie müssten für jedes Array eine lustige Gegenmanipulation durchführen, aber es sollte funktionieren.

1

Sie haben nicht wirklich genug Informationen gegeben, um zu wissen, was die Alternative ist. Wenn Sie method() wirklich mit allen Kombinationen von Optionen aus $ as, $ bs und $ cs aufrufen wollen, dann machen geschachtelte Schleifen das Richtige.

Sind es die mehrfach verschachtelten Schleifen, die Sie stören, oder die Tatsache, dass methode() aufgerufen wird count ($ as) * count ($ bs) * count ($ cs) mal?

+0

Diese Antwort würde einen ausgezeichneten Kommentar abgeben. :) – bzlm

+0

@bzlm: Ich beanspruche Ignoranz! Ich war damals ein SO n00b! :) – Ether

2

Logischerweise müssen Sie jedes Element irgendwie durchlaufen. Sie schlurfen nur herum.

Wenn mehrere For-Schleifen hässlich aussehen, sollten Sie Ihre Arrays vielleicht in ihre eigenen Klassen einfügen, die ihre eigenen gekapselten "Checks" haben.