1

I've got loads of arrays that are product options (example below):

$option_array[] = array(
    "name" => "delivery",
    "options" => array(
        "sat", "sun")
);
$option_array[] = array(
    "name" => "colour",
    "options" => array(
        "red", "blue", "green")
);
$option_array[] = array(
    "name" => "size",
    "options" => array(
        "small", "medium", "large")
);

What's the best way for me to come up with every permutation as a foreach loop but while being fairly efficient. I need to enter in a value in the database for every possible combination (so that should be 18 values or 18 iterations in this example). How do I get an array of the resulting permutations?

Expected Output:

array(18){
    [0] => array(3){
        "delivery" => "sat",
        "colour" => "red",
        "size" => "small",
    }
    [1] => array(3){
        "delivery" => "sat",
        "colour" => "red",
        "size" => "medium",
    }
    [2] => array(3){
        "delivery" => "sat",
        "colour" => "red",
        "size" => "large",
    }
    [3] => array(3){
        "delivery" => "sat",
        "colour" => "blue",
        "size" => "small",
    }
    [4] => array(3){
        "delivery" => "sat",
        "colour" => "blue",
        "size" => "medium",
    }
    [5] => array(3){
        "delivery" => "sat",
        "colour" => "blue",
        "size" => "large",
    }
    [6] => array(3){
        "delivery" => "sat",
        "colour" => "green",
        "size" => "small",
    }
    [7] => array(3){
        "delivery" => "sat",
        "colour" => "green",
        "size" => "medium",
    }
    [8] => array(3){
        "delivery" => "sat",
        "colour" => "green",
        "size" => "large",
    }
    [9] => array(3){
        "delivery" => "",
        "colour" => "red",
        "size" => "medium",
    }        [10] => array(3){
        "delivery" => "sun",
        "colour" => "red",
        "size" => "small",
    }
    [11] => array(3){
        "delivery" => "sun",
        "colour" => "red",
        "size" => "medium",
    }
    [12] => array(3){
        "delivery" => "sun",
        "colour" => "red",
        "size" => "large",
    }
    [13] => array(3){
        "delivery" => "sun",
        "colour" => "blue",
        "size" => "small",
    }
    [14] => array(3){
        "delivery" => "sun",
        "colour" => "blue",
        "size" => "medium",
    }
    [15] => array(3){
        "delivery" => "sun",
        "colour" => "blue",
        "size" => "large",
    }
    [16] => array(3){
        "delivery" => "sun",
        "colour" => "green",
        "size" => "small",
    }
    [17] => array(3){
        "delivery" => "sun",
        "colour" => "green",
        "size" => "medium",
    }
    [18] => array(3){
        "delivery" => "sun",
        "colour" => "green",
        "size" => "large",
    }
}

I'm not overly bothered about the output format.

ScottMcGready
  • 1,612
  • 2
  • 24
  • 33
  • Every permutation of what exactly? Your array is multidimensional. Please specify your expected output. – tim Sep 06 '13 at 19:52
  • Apologies, hadn't pasted that in - never forget about it either as it bugs me! Give me 2 minutes – ScottMcGready Sep 06 '13 at 19:54
  • possible duplicate of [Finding cartesian product with PHP associative arrays](http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays) – Jon Sep 06 '13 at 20:04
  • Not an exact match (the input would need slight massaging from `name => foo, options => [...]` to straight `foo => [...]`), but it's definitely the cartesian product you are after. – Jon Sep 06 '13 at 20:05
  • More than 3 dimensions and I get an automatic migraine. Thanks for the help guys. – ScottMcGready Sep 06 '13 at 21:41

1 Answers1

0

This works on http://writecodeonline.com/php/ :

$option_array[] = array(
    "name" => "delivery",
    "options" => array(
        "sat", "sun")
);
$option_array[] = array(
    "name" => "colour",
    "options" => array(
        "red", "blue", "green")
);
$option_array[] = array(
    "name" => "size",
    "options" => array(
        "small", "medium", "large")
);

$N = 1;
foreach ($option_array as $options) $N *= count($options['options']);

$all_combinations = array();

for( $i = 0 ; $i < $N ; ++$i )
{
  $all_combinations[$i] = array();
  $q = $i;
  for( $j = count($option_array)-1 ; 0 <= $j ; --$j )
  {
    $opt = $option_array[$j];
    $nopts = count($opt['options']);
    $all_combinations[$i][$opt['name']] = $opt['options'][$q % $nopts];
    $q = floor($q / $nopts);
  }
}

print_r( $all_combinations );
Matt
  • 20,108
  • 1
  • 57
  • 70