I have an array of 18 values:
$array = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r');
I want to split this array into 12 different arrays so it should look like this:
array(
0 => array('a', 'b'),
1 => array('c', 'd'),
2 => array('e', 'f'),
3 => array('g', 'h'),
4 => array('i', 'j'),
5 => array('k', 'l'),
6 => array('m'),
7 => array('n'),
8 => array('o'),
9 => array('p'),
10 => array('q'),
11 => array('r')
)
My function doesn't seem to work
function array_split($array, $parts){
return array_chunk($array, ceil(count($array) / $parts));
}
$result = array_split($array, 12);
because I get 9 different arrays instead of 12. It would return
array(
0 => array('a', 'b'),
1 => array('c', 'd'),
2 => array('e', 'f'),
3 => array('g', 'h'),
4 => array('i', 'j'),
5 => array('k', 'l'),
6 => array('m', 'n'),
7 => array('o', 'p'),
8 => array('q', 'r')
)
How would I go about doing this? Thanks.
This simple function would work for you:
Usage
$array = range("a", "r"); // same as your array
print_r(alternate_chunck($array,12));
Output
Array
(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[0] => c
[1] => d
)
[2] => Array
(
[0] => e
[1] => f
)
[3] => Array
(
[0] => g
[1] => h
)
[4] => Array
(
[0] => i
[1] => j
)
[5] => Array
(
[0] => k
[1] => l
)
[6] => Array
(
[0] => m
)
[7] => Array
(
[0] => n
)
[8] => Array
(
[0] => o
)
[9] => Array
(
[0] => p
)
[10] => Array
(
[0] => q
)
[11] => Array
(
[0] => r
)
)
Update The above might not be useful for most cases ... here is another type of chunk
$array = range("a", "r"); // same as your array
print_r(fill_chunck($array, 5));
Output
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
)
[1] => Array
(
[0] => e
[1] => f
[2] => g
[3] => h
)
[2] => Array
(
[0] => i
[1] => j
[2] => k
[3] => l
)
[3] => Array
(
[0] => m
[1] => n
[2] => o
[3] => p
)
[4] => Array
(
[0] => q
[1] => r
)
)
This would make sure the group at no time is more that 5 elements where the other one has no limitation
Function Used
function alternate_chunck($array, $parts) {
$t = 0;
$result = array();
$max = ceil(count($array) / $parts);
foreach(array_chunk($array, $max) as $v) {
if ($t < $parts) {
$result[] = $v;
} else {
foreach($v as $d) {
$result[] = array($d);
}
}
$t += count($v);
}
return $result;
}
function fill_chunck($array, $parts) {
$t = 0;
$result = array_fill(0, $parts - 1, array());
$max = ceil(count($array) / $parts);
foreach($array as $v) {
count($result[$t]) >= $max and $t ++;
$result[$t][] = $v;
}
return $result;
}
The magic in the math is determining which portion of elements belongs in the first set of chunks where all columns are filled in each row versus which elements belong in the second set (if the set should even exist) where all columns except the right-most column are filled.
Let me draw what I'm talking about. The >
marks the division between the two chunked arrays.
$size = 9; ------------- $size = 9; -------------
$maxRows = 4; 1 | A , B , C | $maxRows = 3; | A , B , C |
$columns = 3; > |-----------| $columns = 3; 1 | D , E , F |
$fullRows = 1; | D , E | $fullRows = 3; | G , H , I |
2 | F , G | > -------------
| H , I | 2 n/a
---------
$size = 18; --------- $size = 17; -------------------------------------
$maxRows = 12; | A , B | $maxRows = 2; 1 | A , B , C , D , E , F , G , H , I |
$columns = 2; | C , D | $columns = 9; > -------------------------------------
$fullRows = 6; | E , F | $fullRows = 1; 2 | J , K , L , M , N , O , P , Q |
1 | G , H | ---------------------------------
| I , J |
| K , L |
> ---------
| M |
| N |
| O |
2 | P |
| Q |
| R |
-----
Code: (Demo)
function double_chunk($array, $maxRows) {
$size = count($array);
$columns = ceil($size / $maxRows);
$lessOne = $columns - 1;
$fullRows = $size - $lessOne * $maxRows;
if ($fullRows == $maxRows) {
return array_chunk($array, $fullRows); // all columns have full rows, don't splice
}
return array_merge(
array_chunk(
array_splice($array, 0, $columns * $fullRows), // extract first set to chunk
$columns
),
array_chunk($array, $lessOne) // chunk the leftovers
);
}
var_export(double_chunk(range('a', 'i'), 3));
If you don't mind the iterated array_splice()
calls, this is more brief and perhaps easier to follow (...perhaps not):
Code: (Demo)
function custom_chunk($array, $maxRows) {
$size = count($array);
$columns = ceil($size / $maxRows);
$lessOne = $columns - 1;
$fullRows = $size - $lessOne * $maxRows;
for ($i = 0; $i < $maxRows; ++$i) {
$result[] = array_splice($array, 0, ($i < $fullRows ? $columns : $lessOne));
}
return $result;
}
var_export(custom_chunk(range('a', 'r'), 12));
You can use array_chunk
and array_merge
for this problem:
<?php
$array = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r');
$chunked_arr = array_chunk($array,12);
$j = 0;
for($i = 0; $i < count($chunked_arr[0]); $i++){
if(!($i % 2 == 0)){
$first_combined[$j][$i % 2] = $chunked_arr[0][$i];
$j++;
} else {
$first_combined[$j][$i % 2] = $chunked_arr[0][$i];
}
}
$merged_array = array_merge($first_combined, $chunked_arr[1]);
echo '<pre>';
print_r($merged_array);
?>
And You will get the result like this:
Array
(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[0] => c
[1] => d
)
[2] => Array
(
[0] => e
[1] => f
)
[3] => Array
(
[0] => g
[1] => h
)
[4] => Array
(
[0] => i
[1] => j
)
[5] => Array
(
[0] => k
[1] => l
)
[6] => m
[7] => n
[8] => o
[9] => p
[10] => q
[11] => r
)
This is what exactly you want.
Live Demo Here>>
ceil(count($array) / $parts)
would give 2, so each array is being filled up with 2 items until you dont have 2 items left. hence the last one has 1 item. this will work when you have a huge amount of data in the array, but not so much when you have a small amount of data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With