1

I have the following array:

$array = array(
    array("2018","2019"),
    "Jan",
    array("France","Germany")
);

I need a matrix that crosses all the elements of the array; e.g:

array(
    array("2018","Jan","France"),
    array("2018","Jan","Germany"),
    array("2019","Jan","France"),
    array("2019","Jan","Germany")
);

meaning, 2 x 2 x 1 arrays

but this can be that I have more elements that are or are not arrays then:

$array = array(
    array("2018","2019"),
    "Jan",
    array("France","Germany"),
    array("prod1","prod2","prod3"),
    'Act'
);

In this case I would get 2 x 2 x 1 x 4 x 1 arrays in the end.

Any idea on how to achieve this?

Darragh Enright
  • 13,676
  • 7
  • 41
  • 48
laloune
  • 548
  • 1
  • 9
  • 26
  • did you try something ? – ᴄʀᴏᴢᴇᴛ Aug 07 '17 at 14:12
  • not yet, I am rather looking for an orientation thus. I wonder whether loops would work since the number of arrays can be variable – laloune Aug 07 '17 at 14:14
  • You can loop through the main array and detect the whether each element is array. Maybe you can try a recursion.... – lvil Aug 07 '17 at 14:15
  • I think recursion is the easiest solution. Have a look here https://stackoverflow.com/questions/8567082/how-to-generate-in-php-all-combinations-of-items-in-multiple-arrays this might help you – ᴄʀᴏᴢᴇᴛ Aug 07 '17 at 14:17
  • Possible duplicate of [How to generate in PHP all combinations of items in multiple arrays](https://stackoverflow.com/questions/8567082/how-to-generate-in-php-all-combinations-of-items-in-multiple-arrays) – ᴄʀᴏᴢᴇᴛ Aug 07 '17 at 14:19

1 Answers1

1

Is that what you are looking for ?

$dst = array(array());
foreach ($array as $idx => $val) {
    foreach ($dst as $tmp_idx => $tmp_array) {
        if (is_array($val)) {
            foreach ($val as $sub_idx => $sub_val) {
                $dst[] = array_merge($dst[$tmp_idx], array(count($dst[$tmp_idx]) => $sub_val));
            }
        } else {
            $dst[] = array_merge($dst[$tmp_idx], array(count($dst[$tmp_idx]) => $val));
        }
        unset($dst[$tmp_idx]);
    }
}
  • I declare the array with an empty array in it.
  • A first foreach iterates through the main array to access all the categories, whatever their number.
  • A second foreach iterates through the result array.
  • A third foreach - or not, depending if the category contains several or a single entry - iterates through each entry of the current category and merges an array containing only that current category in the result currently iterated on (from $dst). The merge is pushed into the result array. The result stored in $dst are assumed to be temporary and will be copied and completed with each new value, making them progressively contain one entry from each category.
  • At the end of each iteration on $dst, the current temporary result is removed from the array since it has no purpose : if the foreach iterated on it, that means that it was incomplete.
  • At the end, the only entries in $dst that remain are these who weren't iterated on, meaning that every entry from each category were considered when they were created, meaning that they are complete.

  • I'm available for any clarification may the need arise.

Sarkouille
  • 1,275
  • 9
  • 16
  • I guess it can be optimised, especially regarding the `unset()` part, but I haven't slept for a day and a half and answer from work, I believe my brains are a little off. – Sarkouille Aug 07 '17 at 14:25
  • While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – ᴄʀᴏᴢᴇᴛ Aug 07 '17 at 14:27
  • @ᴄʀᴏᴢᴇᴛ I fully agree with that, I'm definitely dizzy, my apologies. – Sarkouille Aug 07 '17 at 14:29
  • this is definitely what I am looking for. Thanks a lot. I will analyze it further to understand what it does step by step. – laloune Aug 07 '17 at 14:32
  • @laloune I'm deeply sorry for the lack of explaination about what the code does/how it works. I've fixxed that. – Sarkouille Aug 07 '17 at 14:38
  • 1
    gee thanks a bunch ksjohn for this complete explanation! this brings a lot of value added – laloune Aug 10 '17 at 13:08