laloune
laloune

Reputation: 673

Convert multi-dimensional array into matrix-like array

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?

Upvotes: 1

Views: 294

Answers (1)

Sarkouille
Sarkouille

Reputation: 1232

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.

Upvotes: 1

Related Questions