Skip to content

Commit

Permalink
[12.x] Feature: Collection chunk without preserving keys (#54916)
Browse files Browse the repository at this point in the history
* add test

* implement chunking without preserving keys for support collection

* implement chunking without preserving keys for lazy collection
  • Loading branch information
liamduckett authored Mar 6, 2025
1 parent 7b42047 commit 77672fd
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
5 changes: 3 additions & 2 deletions src/Illuminate/Collections/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1441,17 +1441,18 @@ public function firstOrFail($key = null, $operator = null, $value = null)
* Chunk the collection into chunks of the given size.
*
* @param int $size
* @param bool $preserveKeys
* @return static<int, static>
*/
public function chunk($size)
public function chunk($size, $preserveKeys = true)
{
if ($size <= 0) {
return new static;
}

$chunks = [];

foreach (array_chunk($this->items, $size, true) as $chunk) {
foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) {
$chunks[] = new static($chunk);
}

Expand Down
12 changes: 9 additions & 3 deletions src/Illuminate/Collections/LazyCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1376,22 +1376,28 @@ public function firstOrFail($key = null, $operator = null, $value = null)
* Chunk the collection into chunks of the given size.
*
* @param int $size
* @param bool $preserveKeys
* @return static<int, static>
*/
public function chunk($size)
public function chunk($size, $preserveKeys = true)
{
if ($size <= 0) {
return static::empty();
}

return new static(function () use ($size) {
$add = match ($preserveKeys) {
true => fn (array &$chunk, Traversable $iterator) => $chunk[$iterator->key()] = $iterator->current(),
false => fn (array &$chunk, Traversable $iterator) => $chunk[] = $iterator->current(),
};

return new static(function () use ($size, $add) {
$iterator = $this->getIterator();

while ($iterator->valid()) {
$chunk = [];

while (true) {
$chunk[$iterator->key()] = $iterator->current();
$add($chunk, $iterator);

if (count($chunk) < $size) {
$iterator->next();
Expand Down
18 changes: 18 additions & 0 deletions tests/Support/SupportCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,24 @@ public function testChunkWhenGivenLessThanZero($collection)
);
}

#[DataProvider('collectionClassProvider')]
public function testChunkPreservingKeys($collection)
{
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$this->assertEquals(
[[0 => 1, 1 => 2, 2 => 3], [3 => 4, 4 => 5, 5 => 6], [6 => 7, 7 => 8, 8 => 9], [9 => 10]],
$data->chunk(3)->toArray()
);

$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$this->assertEquals(
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]],
$data->chunk(3, false)->toArray()
);
}

#[DataProvider('collectionClassProvider')]
public function testSplitIn($collection)
{
Expand Down

0 comments on commit 77672fd

Please sign in to comment.