1

I know this question popped up alot of times here. I did search before but didn't find anything that fits.

I'm sitting here since like 5 hours and my brain is not getting me anywhere at the moment. D:

I've got an array:

[rahmenfarbe] => Array
(
         [0] => Graphite
         [1] => Aluminium
         [2] => Smoke
)
[rueckenunterstuetzung] => Array
(
         [0] => PostureFit
         [1] => LumbalSupport
)
[armauflagen] => Array
(
         [0] => Leder
         [1] => Vinyl
)
[rollen] => Array
(
         [0] => Teppichrollen
         [1] => Hartbodenrollen
)

And I want to create an array which contains all possible combinations of the above (child-)options.

Example:

[0] => Array
(
    [rahmenfarbe] => Graphite
    [rueckenunterstuetzung] => PostureFit
    [armauflagen] => Leder
    [rollen] => Teppichrollen
)

[1] => Array
(
    [rahmenfarbe] => Aluminium
    [rueckenunterstuetzung] => PostureFit
    [armauflagen] => Leder
    [rollen] => Teppichrollen
)

[2] => Array
(
    [rahmenfarbe] => Smoke
    [rueckenunterstuetzung] => PostureFit
    [armauflagen] => Leder
    [rollen] => Teppichrollen
)

[3] => Array
(
    [rahmenfarbe] => Graphite
    [rueckenunterstuetzung] => LumbalSupport
    [armauflagen] => Leder
    [rollen] => Teppichrollen
)

[4] => Array
(
    [rahmenfarbe] => Aluminium
    [rueckenunterstuetzung] => LumbalSupport
    [armauflagen] => Leder
    [rollen] => Teppichrollen
)

[5] => Array
(
    [rahmenfarbe] => Smoke
    [rueckenunterstuetzung] => LumbalSupport
    [armauflagen] => Leder
    [rollen] => Teppichrollen
)

[6] => Array
(
    [rahmenfarbe] => Graphite
    [rueckenunterstuetzung] => PostureFit
    [armauflagen] => Vinyl
    [rollen] => Teppichrollen
)

Thats the code I've got so far:

$template = "test";
$maxCombinations = 0;
$optionKeys = array_keys($options);
foreach($optionKeys as $index => $optionKey) {
    $indexCounters[$optionKey] = 0;
    $maxCombinations += count($options[$optionKey]);
}
$maxCombinations *= count($options);
echo "Max: {$maxCombinations}\n\n";

$i1 = 0;
$i2 = 0;
while (true) {
    // ** Debug Output
    echo str_repeat("-", 80) . "\n";
    print_r($indexCounters);
    echo str_repeat("-", 80) . "\n";
    // ** Debug Output

    foreach ($optionKeys as $optionKey) {
        $matrix[$template][$combinationsCount][$optionKey] = $options[$optionKey][$indexCounters[$optionKey]];

        echo "[DEBUG] matrix[\"{$template}\"][\"{$combinationsCount}\"][\"{$optionKey}\"] = options[\"{$optionKey}\"][\"{$indexCounters[$optionKey]}\"] ({$options[$optionKey][$indexCounters[$optionKey]]})\n";
    }
    $combinationsCount++;
    echo str_repeat("-", 80) . "\n";

    $indexCounters[$optionKeys[$i1]]++;
    if ($indexCounters[$optionKeys[$i1]] >= count($options[$optionKeys[$i1]])) {
        $i1 = 0;
        $i2++;
        if ($i2 >= count($options))
            break;
        for ($a = 0; $a < $i2; $a++)
            $indexCounters[$optionKeys[$a]] = 0;
        $indexCounters[$optionKeys[$i2]]++;
    }
}
print_r($matrix);

Basically it works. But it does not generate all possible combinations. From debug output I see that the counters $i1 and $i2 do not behave like I thought and thus ending the loop too early. Guess I need to figure that out tomorrow. Already too late (3:58 am) anyway ...

But maybe one of you kind guys got another bright idea how to solve that? Maybe something recursive? Thought about that but didn't attempt an implementation yet.

Any help is appreciated! :)

Thanks!

Mario Werner
  • 1,771
  • 14
  • 24
  • Look up "cartesian product" - there are plenty of solutions . – georg Jan 25 '15 at 03:07
  • possible duplicate of [Permutation of Array PHP](http://stackoverflow.com/questions/10734514/permutation-of-array-php), plus: http://stackoverflow.com/search?q=php+array+permutation – CBroe Jan 25 '15 at 03:17
  • Thanks @georg! Searching for it I found a similar problem here on SO with basically the same problem: http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays - Solution seems to work at the first impressions. Need to check that more detailed later. – Mario Werner Jan 25 '15 at 03:20

1 Answers1

3

This is you are trying to do , use Permutation of array in php i. e Cartesian product of array.

function cartesian($input) {
    $result = array();

    while (list($key, $values) = each($input)) {

        if (empty($values)) {
            continue;
        }
        if (empty($result)) {
            foreach($values as $value) {
                $result[] = array($key => $value);
            }
        }
        else {

            $append = array();

            foreach($result as &$product) {

                $product[$key] = array_shift($values);
                $copy = $product;
                foreach($values as $item) {
                    $copy[$key] = $item;
                    $append[] = $copy;
                }
                array_unshift($values, $product[$key]);
            }
            $result = array_merge($result, $append);
        }
    }

    return $result;
}
$input=array('rahmenfarbe' => array
(
    0 => 'Graphite',
    1 => 'Aluminium',
    2 => 'Smoke',
),
'rueckenunterstuetzung' => array
(
    0 => 'PostureFit',
    1 => 'LumbalSupport',
),
'armauflagen' => array
(
    0 => 'Leder',
    1 => 'Vinyl',
),
'rollen' => array
(
    0 => 'Teppichrollen',
    1 => 'Hartbodenrollen',
));

echo '<pre>';
print_r(cartesian($input));
echo '</pre>';

Courtesy:@georg & CBroe

A l w a y s S u n n y
  • 36,497
  • 8
  • 60
  • 103