Я пишу сайт электронной коммерции и нуждаюсь в хорошем способе рассчитать вариации продукта. На сайте есть продукты, продукты могут иметь множество групп опций, группы опций могут иметь много вариантов.
Итак, у продукта Tshirt есть 3 группы опций и опции:
Размер : Маленький, Средний, Большой,
Цвет : красный, синий, желтый, черный,
Материал : Хлопок, нейлон,
который создает: маленький красный хлопок, маленький красный нейлон, маленький синий хлопок, маленький синий нейлон, … так далее и т. д.
Я знаю, что скрипт ниже работает, но также и то, что он может быть оптимизирован. Может ли кто-нибудь представить лучший рабочий пример? Это должно быть возможно, используя рекурсию, но … но я поражаю мысленный блок.
if(count($option_groups) > 1) { // start the variants up foreach($option_groups[0]->get_options() as $option) { $variants[] = array($option); } // go through every other option group to make combos for($x = 1; $x < count($option_groups); $x++) { $combos = array(); foreach($variants as $variant) { $new = array(); foreach($option_groups[$x]->get_options() as $option) { $tmp = $variant; $tmp[] = $option; $new[] = $tmp; } $combos[] = $new; } $variants = array(); foreach($combos as $combo) { foreach($combo as $tmp) { $variants[] = $tmp; } } } }
Это не очень чувствительно к времени, но я бы хотел иметь более удобный номер кода, это довольно грубо.
Также эта проблема (я чувствую, что это не оригинальная проблема, многие тележки делают это) имеют имя? Я не тянул за эту проблему в Google.
EDIT. Это то, что я закончил, основанный на решении для получения прибыли, но поддерживает мои объекты вместо того, чтобы давать мне варианты на один вариант, объединенный как строка. Все спасибо Profitphp!
private function _possible_combos($groups, $prefix = array()) { $result = array(); $group = array_shift($groups); foreach($group->get_options() as $selected) { if($groups) { $tmp = $prefix; $tmp[] = $selected; $result = array_merge($result, $this->_possible_combos($groups, $tmp)); } else { $tmp = $prefix; $tmp[] = $selected; $result[] = $tmp; } } return $result; }
Это должно сделать трюк:
<? $data[]=array('shirt'); $data[]=array('red','yellow','black'); $data[]=array('small','medium','large'); $combos=possible_combos($data); //calculate all the possible comobos creatable from a given choices array function possible_combos($groups, $prefix='') { $result = array(); $group = array_shift($groups); foreach($group as $selected) { if($groups) { $result = array_merge($result, possible_combos($groups, $prefix . $selected. ' ')); } else { $result[] = $prefix . $selected; } } return $result; } echo count($combos) . "\n"; print_r($combos);
Протестировано: http://www.ideone.com/NZE5S
Если это сайт электронной коммерции, я предполагаю, что ваши группы опций уже находятся в базе данных SQL, поэтому почему бы просто не позволить SQL делать комбинации для вас.
SELECT Size.Name, Color.Name, Material.Name FROM Size, Color, Material
Но что, если у вас были все ваши варианты в одной таблице с внешним ключом для группы, в которой она находится …
SELECT r1.Name, r2.Name, r3.Name FROM Options r1, Options r2, Options r3 WHERE r1.GroupID = 1 -- id for Size AND r2.GroupID = 2 -- id for Color AND r3.GroupID = 3 -- id for Material
Когда у вас есть массив, содержащий идентификаторы групп, генерирующие приведенный выше оператор SQL, тривиален (просто конкатенация нескольких строк).