Reputation: 655
I need to split array for 4 arrays next way. How can I do it more elegant? Each element goes to subarray while parent array not empty.
$mainblocks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
$sliders = [];
$slider_index = 0;
foreach ($mainblocks as $mainblock) {
$sliders[$slider_index][] = $mainblock;
if ($slider_index >= 3) {
$slider_index = 0;
continue;
}
$slider_index++;
}
print_r($sliders);
The expected output is: [[1,5,9] [2,6,10] [3,7,11] [4,8,12]]
Upvotes: 0
Views: 144
Reputation: 47902
You want to chunk and transpose.
Here is a one-liner using array_map() and the splat operator (...
) to unpack the chunks. Notice that if the chunks aren't even, you get NULL placeholding elements.
If you don't want NULL placeholders, you'll need to use foreach loops instead of array_map.
Code: (Demo)
$mainblocks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var_export(array_map(null, ...array_chunk($mainblocks, 4)));
echo "\n---\n";
$mainblocks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var_export(array_map(null, ...array_chunk($mainblocks, 4)));
Output:
array (
0 =>
array (
0 => 1,
1 => 5,
2 => 9,
),
1 =>
array (
0 => 2,
1 => 6,
2 => 10,
),
2 =>
array (
0 => 3,
1 => 7,
2 => 11,
),
3 =>
array (
0 => 4,
1 => 8,
2 => 12,
),
)
---
array (
0 =>
array (
0 => 1,
1 => 5,
2 => 9,
),
1 =>
array (
0 => 2,
1 => 6,
2 => 10,
),
2 =>
array (
0 => 3,
1 => 7,
2 => NULL,
),
3 =>
array (
0 => 4,
1 => 8,
2 => NULL,
),
)
If you want to traverse the input array only once and NOT create null
elements, you can push elements based on a modulus calculation with the desired row size. Demo
$size = intdiv(count($mainblocks), 3);
$result = [];
foreach ($mainblocks as $i => $v) {
$result[$i % $size][] = $v;
}
var_export($result);
Upvotes: 2
Reputation: 12937
Take a look at array_chunk()
:
$input_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
print_r(array_chunk($input_array, 3)); // output: [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
Description:
array_chunk ( array $array , int $size [, bool $preserve_keys = FALSE ] ) : array
Chunks an array into arrays with size elements. The last chunk may contain less than size elements.
Edit:
For your requirements:
$mainblocks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
for($i = 0; $i <= sizeof($mainblocks) / 4; $i++)
for($j = 1; $j <= sizeof($mainblocks); $j = $j + 4)
$sliders[$i][] = $mainblocks[$j - 1 + $i];
print_r($sliders); // output: [[1,5,9] [2,6,10] [3,7,11] [4,8,12]]
Upvotes: 2