Skip to content

Commit 809fdba

Browse files
authored
[8.x] chunkWhile(): preserve keys, defer to lazy collections (#33999)
* chunkWhile(): defer to lazy collection method * chunkWhile(): preserve keys and pass whole chunk to callback * chunkWhile(): ensure lazy collection is lazy * chunkWhile(): fix indenting 😅 * chunkWhile() fix Equal Elements test callback
1 parent 384109a commit 809fdba

File tree

4 files changed

+45
-35
lines changed

4 files changed

+45
-35
lines changed

src/Illuminate/Collections/Collection.php

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,23 +1078,9 @@ public function chunk($size)
10781078
*/
10791079
public function chunkWhile(callable $callback)
10801080
{
1081-
$chunks = [];
1082-
1083-
$chunk = [];
1084-
1085-
foreach ($this->items as $current) {
1086-
if (isset($previous) && ! $callback($previous, $current)) {
1087-
$chunks[] = new static($chunk);
1088-
$chunk = [];
1089-
}
1090-
1091-
$chunk[] = $current;
1092-
$previous = $current;
1093-
}
1094-
1095-
$chunks[] = new static($chunk);
1096-
1097-
return new static($chunks);
1081+
return new static(
1082+
$this->lazy()->chunkWhile($callback)->mapInto(static::class)
1083+
);
10981084
}
10991085

11001086
/**

src/Illuminate/Collections/LazyCollection.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,22 +1093,29 @@ public function chunkWhile(callable $callback)
10931093
return new static(function () use ($callback) {
10941094
$iterator = $this->getIterator();
10951095

1096-
$chunk = [];
1096+
$chunk = new Collection();
1097+
1098+
if ($iterator->valid()) {
1099+
$chunk[$iterator->key()] = $iterator->current();
1100+
1101+
$iterator->next();
1102+
}
10971103

10981104
while ($iterator->valid()) {
1099-
if (isset($previous) && ! $callback($previous, $iterator->current())) {
1105+
if (! $callback($iterator->current(), $iterator->key(), $chunk)) {
11001106
yield new static($chunk);
11011107

1102-
$chunk = [];
1108+
$chunk = new Collection();
11031109
}
11041110

1105-
$chunk[] = $iterator->current();
1106-
$previous = $iterator->current();
1111+
$chunk[$iterator->key()] = $iterator->current();
11071112

11081113
$iterator->next();
11091114
}
11101115

1111-
yield new static($chunk);
1116+
if ($chunk->isNotEmpty()) {
1117+
yield new static($chunk);
1118+
}
11121119
});
11131120
}
11141121

tests/Support/SupportCollectionTest.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,15 +1650,15 @@ public function testChunkWhenGivenLessThanZero($collection)
16501650
public function testChunkWhileOnEqualElements($collection)
16511651
{
16521652
$data = (new $collection(['A', 'A', 'B', 'B', 'C', 'C', 'C']))
1653-
->chunkWhile(function ($previous, $current) {
1654-
return $previous === $current;
1653+
->chunkWhile(function ($current, $key, $chunk) {
1654+
return $chunk->last() === $current;
16551655
});
16561656

16571657
$this->assertInstanceOf($collection, $data);
16581658
$this->assertInstanceOf($collection, $data->first());
1659-
$this->assertEquals(['A', 'A'], $data->first()->toArray());
1660-
$this->assertEquals(['B', 'B'], $data->get(1)->toArray());
1661-
$this->assertEquals(['C', 'C', 'C'], $data->last()->toArray());
1659+
$this->assertEquals([0 => 'A', 1 => 'A'], $data->first()->toArray());
1660+
$this->assertEquals([2 => 'B', 3 => 'B'], $data->get(1)->toArray());
1661+
$this->assertEquals([4 => 'C', 5 => 'C', 6 => 'C'], $data->last()->toArray());
16621662
}
16631663

16641664
/**
@@ -1667,17 +1667,17 @@ public function testChunkWhileOnEqualElements($collection)
16671667
public function testChunkWhileOnContiguouslyIncreasingIntegers($collection)
16681668
{
16691669
$data = (new $collection([1, 4, 9, 10, 11, 12, 15, 16, 19, 20, 21]))
1670-
->chunkWhile(function ($previous, $current) {
1671-
return $previous + 1 == $current;
1670+
->chunkWhile(function ($current, $key, $chunk) {
1671+
return $chunk->last() + 1 == $current;
16721672
});
16731673

16741674
$this->assertInstanceOf($collection, $data);
16751675
$this->assertInstanceOf($collection, $data->first());
1676-
$this->assertEquals([1], $data->first()->toArray());
1677-
$this->assertEquals([4], $data->get(1)->toArray());
1678-
$this->assertEquals([9, 10, 11, 12], $data->get(2)->toArray());
1679-
$this->assertEquals([15, 16], $data->get(3)->toArray());
1680-
$this->assertEquals([19, 20, 21], $data->last()->toArray());
1676+
$this->assertEquals([0 => 1], $data->first()->toArray());
1677+
$this->assertEquals([1 => 4], $data->get(1)->toArray());
1678+
$this->assertEquals([2 => 9, 3 => 10, 4 => 11, 5 => 12], $data->get(2)->toArray());
1679+
$this->assertEquals([6 => 15, 7 => 16], $data->get(3)->toArray());
1680+
$this->assertEquals([8 => 19, 9 => 20, 10 => 21], $data->last()->toArray());
16811681
}
16821682

16831683
/**

tests/Support/SupportLazyCollectionIsLazyTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ public function testChunkIsLazy()
2929
});
3030
}
3131

32+
public function testChunkWhileIsLazy()
33+
{
34+
$collection = LazyCollection::make(['A', 'A', 'B', 'B', 'C', 'C', 'C']);
35+
36+
$this->assertDoesNotEnumerateCollection($collection, function ($collection) {
37+
$collection->chunkWhile(function ($current, $key, $chunk) {
38+
return $current === $chunk->last();
39+
});
40+
});
41+
42+
$this->assertEnumeratesCollection($collection, 7, function ($collection) {
43+
$collection->chunkWhile(function ($current, $key, $chunk) {
44+
return $current === $chunk->last();
45+
})->take(7)->all();
46+
});
47+
}
48+
3249
public function testCollapseIsLazy()
3350
{
3451
$collection = LazyCollection::make([

0 commit comments

Comments
 (0)