2009-07-23 20 views
5

Gdy chcesz sprawdzić/mieć kombinacje elementów tablicy, jak możesz uniknąć foreach zagnieżdżania?: unikanie wielokrotnego zagnieżdżonego foreach

Przykładowy kod:

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

Każdy z alternatywnych metod, które mogą uniknąć zagnieżdżania?

+0

Dlaczego chcesz uniknąć zagnieżdżenia? To, co masz, jest już najbardziej intuicyjnym rozwiązaniem większości problemów. –

+1

Aby wyjaśnić: Chciałbym uniknąć zagnieżdżenia, ponieważ często wydaje się, że naprawdę trudno jest wyświetlać dobrze zakodowane lub czyste. Wiem, że to nie jest powód, żeby się poddawać, ale jeśli jest jakaś alternatywna alternatywa, chciałbym o tym usłyszeć. – koen

+1

Można użyć rekurencji zamiast iteracji. Spowoduje to przeniesienie zagnieżdżenia z kodu do modelu obiektu. (Trudno być dokładniejszym, ponieważ twój przykład jest tak wymyślony.) – bzlm

Odpowiedz

7

Możesz napisać własną klasę Iterator, która implementuje Iterator interface. Możesz wtedy mieć jego konstruktor akceptujący trzy tablice, a następnie możesz go użyć do zapętlenia każdej kombinacji z foreach.

Myślę jednak, że byłoby to znacznie wolniejsze, więc chciałbym tego uniknąć. Ciekawe byłoby poznać powody, dla których chcesz uniknąć zagnieżdżonych pętli foreach?

+0

Byłoby miło, gdyby ktokolwiek, kto mnie głosował, dodałby komentarz –

+0

Tom Nie zgodziłem się na głosowanie, ale jak korzystać z tego interfejsu iteratora? jeśli dasz mi mały algorytm, będzie użyteczny! dzięki! – Neocortex

+0

@BannedfromSO Nie jestem pewien, czy to było naprawdę dobre rozwiązanie - trzy pętle są prawdopodobnie bardziej oczywiste, więc nie jestem pewien, czy ten przykład jest opłacalny. –

1

Czy rozważałeś wzięcie liczby wszystkich macierzy i pomnożenie ich wszystkich razem, aby uzyskać całkowitą liczbę permutacji, a następnie wykonanie dla i it iteracji tego licznika? Musiałbyś wykonać zabawną operację przeciwdziałania dla każdej tablicy, ale powinna działać.

1

Nie podałeś wystarczająco dużo informacji, aby wiedzieć, jaka jest alternatywa. Jeśli naprawdę chcesz wywołać metodę() ze wszystkimi kombinacjami opcji od $ as, $ bs i $ cs, wówczas pętle zagnieżdżone zrobią to, co trzeba.

Czy to zagnieżdżone pętle zwielokrotnione, lub fakt, że metoda() jest wywoływana count ($ as) * count ($ bs) * count ($ cs) times?

+0

Ta odpowiedź byłaby świetnym komentarzem. :) – bzlm

+0

@bzlm: Żądam niewiedzy! Byłem wtedy SO n00b! :) – Ether

2

Logicznie rzecz biorąc, musisz jakoś powtórzyć każdą pozycję. Po prostu tasuje się proces.

Jeśli wiele pętli wygląda brzydko, być może powinieneś umieścić swoje tablice w swoich klasach, które mają własne enkapsulowane "kontrole".