On the topic of transposing a 2d array, if:
- You have a (precisely) 2d array with numeric first level keys and non-numeric second level keys AND
- You need to transpose an array than will be GUARANTEED to have a minimum of 2 rows of data AND
- You don't need to preserve the numeric first level keys after transposing AND
- You have a code styling constraint which forbids using language constructs to iterate, THEN...
Code: (Demo)
var_export(
array_merge_recursive(...$array)
);
The above is more stable than the following script which assumes that all column values will be presented in all rows and be in the same order. Run the following demo to see how 2nd level associations can become broken. (Demo)
var_export(
array_combine(
array_keys($array[array_key_first($array)]),
array_map(null, ...$array)
)
);
Neither of the above is actually suitable for general use; you need to be 100% confident of the data structure for these techniques to return the correct result. To be more explicit about potential corruptions of data, if either technique is given a 2d array containing a single row, then the output will be a flat, associative array -- this is incorrect transposition. If array_merge_recursive() is fed an empty array it will correctly return an empty array. If the array_combine(array_keys(), array_map()) script is given an empty array it will emit a Warning, then a Fatal error.
For a completely stable means of transposition without using language constructs, you can use nested array_walk() calls, but then you are effectively making an uglier, more convoluted version of a nested foreach() loop structure. This doesn't suffer any of the aforementioned caveats and does preserve the initial first level keys. (Demo)
$result = [];
array_walk($array, function ($row, $i) use (&$result) {
array_walk($row, function ($v, $k) use (&$result, $i) {
$result[$k][$i] = $v;
});
});
var_export($result);
If you want a functional style solution that actually offers a returned value, it is again ugly, but you can use array_reduce(). (Demo)
var_export(
array_reduce(
array_keys($array),
function ($result, $i) use ($array) {
array_walk($array[$i], function ($v, $k) use (&$result, $i) {
$result[$k][$i] = $v;
});
return $result;
},
[]
)
);
If using Laravel, there isn't yet a pre-built transpose() method, so you can declare and use a macro() and that is most simply done by implementing language constructs, but if you still want iteration via Laravel methods, here is a way: (PHPize Demo)
var_export(
$collection->reduce(
function($result, $row, $i) {
collect($row)->each(function($v, $k) use (&$result, $i) {
$result[$k][$i] = $v;
});
return $result;
},
[]
)
);