Reputation: 25
I'm trying to split the collection into several parts, taking an example from the documentation
$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->all();
I want to get this
[[1, 2, 3, 4], [5, 6, 7]]
But I get this
[
[
1,
2,
3,
4
],
{
"4": 5,
"5": 6,
"6": 7
}
]
I get strange output data, although everything is fine in the documentation
Upvotes: 2
Views: 922
Reputation: 47900
Numerous people have complained over the years that Laravel's collection method chunk()
doesn't follow the same behavior as PHP's native function array_chunk()
.
Still as of Laravel 11, there is no capacity to set a preserveKeys
parameter to false
.
chunkWhile()
offers the same default behavior, so the following is NOT a workaround -- you get the same output as simply calling chunk()
->chunkWhile(fn($v, $k) => $k % 4)
Or
->chunkWhile(fn($v, $k) => $k % 4, false)
For now, there are some workarounds using Laravel methods and a little mathematical preparation.
groupBy()
(PHPize Demo)
var_export(
collect([1, 2, 3, 4, 5, 6, 7])
->groupBy(fn($v, $k) => intdiv($k, 4))
);
split()
(PHPize Demo)
$coll = collect([1, 2, 3, 4, 5, 6, 7]);
var_export(
$coll
->split(ceil($coll->count() / 4))
);
Or with split()
, declare the needed $coll
variable while chaining: (PHPize Demo)
var_export(
collect([1, 2, 3, 4, 5, 6, 7])
->pipe(
fn($coll) => $coll->split(ceil($coll->count() / 4))
)
);
Upvotes: 0
Reputation: 76
The reason behind this seems to be in the way the chunk()
function in Laravel calls the array_chunk()
under the hood with the third parameter set to true
.
If you don't necessarily need to use collections and an array would be enough, this seems to do the trick:
$arr = [1, 2, 3, 4, 5, 6, 7];
$chunks = array_chunk($arr, 4, false);
The code above results in
[[1,2,3,4],[5,6,7]]
Upvotes: 4