0

Any tips on how to do something like this? I have an array like this:

array (
        [a] => array(1,2)
        [b] => array(4,5)
        [c] => array(y,z) 
)

and I want to multiply the keys to get a result like this:

array ( 
   [0]=> array (
           [a]=1
           [b]=4
           [c]=y
        )
   [1]=> array (
           [a]=1
           [b]=4
           [c]=z
        )
   [2]=> array (
           [a]=1
           [b]=5
           [c]=y
        )
   [3]=> array (
           [a]=1
           [b]=5
           [c]=z
        )
   [4]=> array (
           [a]=2
           [b]=4
           [c]=y
        )
   [5]=> array (
           [a]=2
           [b]=4
           [c]=z
        )
   .
   .
   .

Where all combinations of the keys are present. The number of keys and elements will be variable, and it's important to preserve the keys.

If I knew how many keys I was dealing with I'd do something like this:

$return = array(); 
$i=0; 
foreach ($array[a] as $val_a) {
    foreach ($array[b] as $val_b) { 
        foreach ($array[c] as $val_c) { 
             $return[$i][a] = $val_a;
             $return[$i][b] = $val_b;
             $return[$i][c] = $val_b;
             $i++;
        }
    }
 }

I'm sure there's a recursive function to do this, but I can't quite figure out how to do it.

Zarwell
  • 111
  • 8
  • Are you trying to do matrix multiplication? http://stackoverflow.com/questions/25220655/matrix-multiplication-in-php – Jeremy Harris Jul 15 '16 at 19:33
  • @JeremyHarris No, he's creating combination, not multiplying numbers. – Barmar Jul 15 '16 at 19:40
  • @Barmar Seemed odd to me, the title said "Multiply". – Jeremy Harris Jul 15 '16 at 19:41
  • Did you read the question itself, not just the title? – Barmar Jul 15 '16 at 19:42
  • No, I don't think it's matrix multiplication. "Multiply" may not have been the right choice of words. I made an edit to hopefully clarify what I'm trying to do. – Zarwell Jul 15 '16 at 19:49
  • I have an answer [here](http://stackoverflow.com/questions/13742093/create-array-with-all-unique-combinations/13742505#13742505) that shows how to do something similar in Javascript. I think you should be able to adapt it to PHP. – Barmar Jul 15 '16 at 20:30
  • Barmer, that was extremely helpful. I adapted it to PHP and my array and posted it as the solution. Thank you! – Zarwell Jul 17 '16 at 19:19
  • And, I changed the title to "combine" instead of "multiply" – Zarwell Jul 17 '16 at 19:20
  • 4
    Duplicate of "[Concatenate values of n arrays in php](http://stackoverflow.com/q/2246493/90527)", "[PHP 2D Array output all combinations](http://stackoverflow.com/q/2516599/90527)" and many others. The asked-for operation is called the Cartesian product or set cross product. – outis Jul 17 '16 at 19:29

1 Answers1

0

OK, after looking at Barmer's solution in Javascript and adapting it to PHP and the structure of my array, this is what I came up with. Seems to be working well!

$array = array();
$array["a"] = array (1, 2);
$array["b"] = array (4, 5);
$array["c"] = array ("a","b");

$keys = array_keys($array);

$indices = array();
$lengths = array();

for ($i = 0; $i<count($array); $i++) {
    $indices[$i] = 0;
    $lengths[$i] = count($array[$keys[$i]]);
}

$matches = array();

while ($indices[0] < $lengths[0]) {
    $row = array();
    for ($i = 0; $i<count($indices); $i++) {
       $row[$keys[$i]] = $array[$keys[$i]][$indices[$i]];
    }
    $matches[] = $row;
    for ($j = count($indices)-1; $j >= 0; $j--) {
        $indices[$j]++;
        if ($indices[$j] >= $lengths[$j] && $j != 0) {
            $indices[$j] = 0;
        } else {
            break;
        }
    }
}

print_r ($matches);

Result:

[
  {
     0: {
       a: "1",
       b: "4",
       c: "a"
       },
     1: {
       a: "1",
       b: "4",
       c: "b"
       },
     2: {
       a: "1",
       b: "5",
       c: "a"
      },
    3: {
       a: "1",
       b: "5",
       c: "b"
       },
    4: {
       a: "2",
       b: "4",
       c: "a"
       },
    5: {
       a: "2",
       b: "4",
       c: "b"
       },
    6: {
       a: "2",
       b: "5",
       c: "a"
       },
    7: {
       a: "2",
       b: "5",
       c: "b"
       }
    }
]
Community
  • 1
  • 1
Zarwell
  • 111
  • 8