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\',
Can you try using the following simple function?
$cols = array2cols($array,12);
function array2cols($array,$n){
$groups = array();
for($i=0;$i<$n;$i++){
$groups[$i] = array();
}
$col = 0;
foreach($array as $row){
$groups[$col][] = $row;
$col = ($col+1)%$n;
}
return $groups;
}
<?php
$array = range('a','r');
$length = array(2=>6,1=>6); // 2=>6 means -- first six elements of new array will have 2 elements each and then, 1=>6 means -- next six elements of new array will have 1 element each
$target = array(); // or use [] in PHP 5.4
foreach($length as $i=>$times) {
while($times>0){
$target[] = array_splice($array, 0, $i);
$times--;
}
}
print_r($target);
?>
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));
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.
I believe the problem is that you are using a size of 2 when using array_chunk. This ensures that each new array created has two items in it if possible. This causes the function to run out of variables to put into the new arrays by the time you get to 10. You can find the manual on the function here http://php.net/manual/en/function.array-chunk.php Hope this helps