wonza
wonza

Reputation: 302

Get all combinations from multiple nested arrays

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!

Upvotes: 6

Views: 1753

Answers (3)

redShadow
redShadow

Reputation: 6777

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..

Upvotes: 9

JYelton
JYelton

Reputation: 36512

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)
*/
?>

Upvotes: 1

nickb
nickb

Reputation: 59699

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];

Upvotes: 0

Related Questions