6

I'm trying to come up with an algorithm in PHP to get all the combinations for a nested array:

Array
(
    [0] => Array
        (
            [0] => Option Object
                (
                    [strValue] => rough
                )

            [1] => Option Object
                (
                    [strValue] => smooth
                )

            [2] => Option Object
                (
                    [strValue] => coarse
                )

        )

    [1] => Array
        (
            [0] => Option Object
                (
                    [strValue] => shiney
                )

            [1] => Option Object
                (
                    [strValue] => mat
                )

        )

    [2] => Array
        (
            [0] => Option Object
                (
                    [strValue] => Large
                )

            [1] => Option Object
                (
                    [strValue] => Medium
                )

            [2] => Option Object
                (
                    [strValue] => Small
                )

            [3] => Option Object
                (
                    [strValue] => very large
                )

        )

)

So I would get something back like:

-rough, shiney, Large

-rough, shiney, Small

-rough, shiney, Medium

-rough, shiney, Very Large

-smooth, shiney, Large

-smooth, shiney, Small

-smooth, shiney, Medium

-smooth, shiney, Very Large

etc (should be 24 in this example)

I've tried through various foreach examples and some basic recursive function, but I seem to be getting no where fast. If anyone could give a basic outline of how to solve this I'd be very grateful, thanks!

5
  • 1
    and how exactly is your code (which would ideally be added to the question) failing? Because at first sight a set of 3 nested for loops should be all that's needed to solve your problem. Commented Feb 14, 2012 at 0:39
  • 1
    I wouldn't say the arrays are nested, necessarily. They are all contained in a parent array, but they aren't nested with respect to each other. But to create a cartesian product using them all, you do want nested loops. Commented Feb 14, 2012 at 0:55
  • possible duplicate of Finding cartesian product with PHP associative arrays Commented Feb 14, 2012 at 1:04
  • 1
    Well its not necessarily just 3 foreach's needed. The above can have any number of extra elements Commented Feb 14, 2012 at 1:08
  • Just had a chance try out the cartesian function you mentioned, that worked perfectly thanks! Commented Feb 14, 2012 at 2:07

3 Answers 3

9

I just wrote this, that works for arrays of any length..

<?php

function cartesian_product($a) {
  $result = array(array());
  foreach ($a as $list) {
    $_tmp = array();
    foreach ($result as $result_item) {
      foreach ($list as $list_item) {
        $_tmp[] = array_merge($result_item, array($list_item));
      }
    }
    $result = $_tmp;
  }
  return $result;
}


// Let's test this..                                                                                                                                                                                    

header('Content-type: text/plain');

$a = array(
  array('rough','smooth','coarse'),
  array('shiney','mat'),
  array('small','medium','large','x-large'),
);

$result = cartesian_product($a);
foreach ($result as $row) {
  print implode(", ", $row) ."\n";
}

edit: Improved the code a bit..

Sign up to request clarification or add additional context in comments.

1 Comment

Oh, and just fyi, in Python you would do this: stackoverflow.com/questions/533905/… :)
1

Time to nest some foreach loops!

<?php
$array1 = array('rough', 'smooth', 'coarse');
$array2 = array('shiny', 'matte');
$array3 = array('very large', 'large', 'medium', 'small');

foreach($array1 as $i)
    foreach($array2 as $j)
        foreach($array3 as $k)
            $output[] = "$i, $j, $k";

var_dump($output);
/* ouput
array
  0 => string 'rough, shiny, very large' (length=24)
  1 => string 'rough, shiny, large' (length=19)
  2 => string 'rough, shiny, medium' (length=20)
  3 => string 'rough, shiny, small' (length=19)
  4 => string 'rough, matte, very large' (length=24)
  5 => string 'rough, matte, large' (length=19)
  6 => string 'rough, matte, medium' (length=20)
  7 => string 'rough, matte, small' (length=19)
  8 => string 'smooth, shiny, very large' (length=25)
  9 => string 'smooth, shiny, large' (length=20)
  10 => string 'smooth, shiny, medium' (length=21)
  11 => string 'smooth, shiny, small' (length=20)
  12 => string 'smooth, matte, very large' (length=25)
  13 => string 'smooth, matte, large' (length=20)
  14 => string 'smooth, matte, medium' (length=21)
  15 => string 'smooth, matte, small' (length=20)
  16 => string 'coarse, shiny, very large' (length=25)
  17 => string 'coarse, shiny, large' (length=20)
  18 => string 'coarse, shiny, medium' (length=21)
  19 => string 'coarse, shiny, small' (length=20)
  20 => string 'coarse, matte, very large' (length=25)
  21 => string 'coarse, matte, large' (length=20)
  22 => string 'coarse, matte, medium' (length=21)
  23 => string 'coarse, matte, small' (length=20)
*/
?>

1 Comment

thanks for providing the output that made the reply easy to validate
0

Here is the brute force (worst efficiency) algorithm in psuedo-PHP:

$array1 = $array[0];
$array2 = $array[1];
$array3 = $array[2];

$results = array();
for( $i = 0; $i < count( $array1); $i++)
    for( $j = 0; $j < count( $array2); $j++)
        for( $k = 0; $k < count( $array3); $k++)
            $results[] = $array1[$i] . ',' . $array2[$j] . ',' . $array3[$k];

2 Comments

As I just commented above, its not necessarily just 3 foreach's needed. The above can have any number of extra elements, this is dynamic, so I can't just limit it to 3 nested for/foreach
Oh, my mistake. Your title is misleading, as it specifically says 3 arrays.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.