2009-07-23 10 views
5

Quando è necessario verificare/avere combinazioni di elementi di matrice, come evitare di annidarsi?: evitare più foreground annidati

codice Esempio:

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

Chiunque con approcci alternativi che possono evitare la nidificazione?

+0

Perché vuoi evitare di annidare? Quello che hai è già la soluzione più intuitiva per la maggior parte dei problemi. –

+1

Per chiarire: vorrei evitare il nesting perché spesso sembra essere davvero difficile da visualizzare ben codificato o pulito. So che non è un motivo per rinunciarvi, ma se c'è un'alternativa più pulita/più carina mi piacerebbe sentirne parlare. – koen

+1

È possibile utilizzare la ricorsione anziché l'iterazione. Questo sposterà il nesting dal tuo codice nel modello a oggetti. (È difficile essere più specifici dal momento che il tuo esempio è così inventato.) – bzlm

risposta

7

È possibile scrivere la propria classe Iterator che implementa lo Iterator interface. Potresti quindi fare in modo che il costruttore accetti i tre array e quindi puoi usarlo per ripetere su ogni combinazione con foreach.

Tuttavia penso che questo sarebbe molto più lento, quindi vorrei evitarlo. Sarebbe interessante sapere i motivi per cui vuoi evitare i cicli foreach annidati?

+0

Sarebbe bello se chi mi ha votato ingiustificato aggiungesse un commento –

+0

Tom non ho votato, ma io come usare questa interfaccia iteratore? se mi dai un piccolo algoritmo sarà utile! Grazie! – Neocortex

+0

@BannedfromSO Non sono proprio sicuro che questa sia stata davvero una buona soluzione - tre loop sono probabilmente più ovvi, quindi non sono sicuro che l'esempio sia utile –

1

Hai considerato di prendere il conteggio di ciascun array e moltiplicarli tutti insieme per ottenere un numero totale di permutazioni, e quindi di fare un i per iterare quel conteggio? Dovresti fare qualche divertente contromossa per ogni array, ma dovrebbe funzionare.

1

Non hai dato abbastanza informazioni per sapere qual è l'alternativa. Se vuoi davvero chiamare method() con tutte le combinazioni di opzioni da $ as, $ bs e $ cs, allora i cicli annidati faranno la cosa giusta.

Sono i cicli multipli annidati che ti infastidiscono o il fatto che metodo() viene chiamato conteggio ($ as) * conteggio ($ bs) * conteggio ($ cs) volte?

+0

Questa risposta farebbe un commento eccellente. :) – bzlm

+0

@ bzlm: rivendico ignoranza! Allora ero un SO n00b! :) – Ether

2

Logicamente, è necessario scorrere in ogni modo attraverso ciascun elemento. Stai solo mescolando il processo.

Se i loop multipli sembrano brutti, forse dovresti mettere i tuoi array nelle loro classi, che hanno i loro 'assegni' incapsulati.