2009-07-23 3 views
5

Когда вам нужно проверить/иметь комбинации элементов массива, как вы можете избежать вложенности foreach?комбинации: избегать множественных вложенных foreach

Пример кода:

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

Любой с альтернативными подходами, которые могут избежать вложенности?

+0

Почему вы хотите избежать гнездования? То, что у вас есть, является самым интуитивным решением для большинства проблем. –

+1

Чтобы уточнить: я хотел бы избежать гнездования, потому что часто кажется, что очень сложно отображать хорошо закодированные или чистые. Я знаю, что это не повод отказаться от этого, но если есть альтернатива оплодотворения/slicker, я бы хотел услышать об этом. – koen

+1

Вы можете использовать рекурсию вместо итерации. Это приведет к перемещению вложенности из вашего кода в объектную модель. (Трудно быть более конкретным, так как ваш пример настолько надуман.) – bzlm

ответ

7

Вы можете написать собственный класс Iterator, который реализует Iterator interface. Затем вы можете использовать его конструктор для трех массивов, а затем вы можете использовать его для циклического использования каждой комбинации с помощью foreach.

Однако я думаю, что это будет значительно медленнее, поэтому я бы избегал этого. Было бы интересно узнать причины, по которым вы хотите избежать вложенных петлей foreach?

+0

Было бы неплохо, если бы кто-то проголосовал за меня, добавит комментарий –

+0

Том, я не проголосовал за вас, но как использовать этот интерфейс итератора? если вы дадите мне небольшой алгоритм, это будет полезно! благодаря! – Neocortex

+0

@BannedfromSO Не совсем уверен, что это действительно хорошее решение - три петли, вероятно, более очевидны, поэтому я не уверен, что пример стоит –

1

Считаете ли вы, что считать количество каждого массива и умножить их все вместе, чтобы получить общее количество перестановок, а затем сделать для i, чтобы итерировать этот счет? Вам нужно было бы сделать несколько смежных манипуляций счетчиком для каждого массива, но он должен работать.

1

Вы не дали достаточно информации, чтобы узнать, что такое альтернатива. Если вы действительно хотите вызывать метод() со всеми комбинациями опций из $ as, $ bs и $ cs, тогда вложенные циклы будут поступать правильно.

Является ли это многократно вложенными циклами, которые вас беспокоят, или тот факт, что метод() вызывается счетчиком ($ as) * count ($ bs) * count ($ cs) раз?

+0

Этот ответ будет отличным комментарием. :) – bzlm

+0

@bzlm: Я утверждаю, что невежество! Тогда я был SO n00b! :) – Ether

2

По логике, вы должны последовательно перебирать каждый элемент. Вы просто перетасовываете процесс.

Если несколько для циклов выглядят уродливыми, возможно, вы должны поместить свои массивы в свои классы, у которых есть свои инкапсулированные «проверки».