diff --git a/src/Illuminate/Collections/Collection.php b/src/Illuminate/Collections/Collection.php index fadcadcfbd67..92c7a5219e0c 100644 --- a/src/Illuminate/Collections/Collection.php +++ b/src/Illuminate/Collections/Collection.php @@ -1078,23 +1078,9 @@ public function chunk($size) */ public function chunkWhile(callable $callback) { - $chunks = []; - - $chunk = []; - - foreach ($this->items as $current) { - if (isset($previous) && ! $callback($previous, $current)) { - $chunks[] = new static($chunk); - $chunk = []; - } - - $chunk[] = $current; - $previous = $current; - } - - $chunks[] = new static($chunk); - - return new static($chunks); + return new static( + $this->lazy()->chunkWhile($callback)->mapInto(static::class) + ); } /** diff --git a/src/Illuminate/Collections/LazyCollection.php b/src/Illuminate/Collections/LazyCollection.php index bc2ac873325c..028f8460a170 100644 --- a/src/Illuminate/Collections/LazyCollection.php +++ b/src/Illuminate/Collections/LazyCollection.php @@ -1093,22 +1093,29 @@ public function chunkWhile(callable $callback) return new static(function () use ($callback) { $iterator = $this->getIterator(); - $chunk = []; + $chunk = new Collection(); + + if ($iterator->valid()) { + $chunk[$iterator->key()] = $iterator->current(); + + $iterator->next(); + } while ($iterator->valid()) { - if (isset($previous) && ! $callback($previous, $iterator->current())) { + if (! $callback($iterator->current(), $iterator->key(), $chunk)) { yield new static($chunk); - $chunk = []; + $chunk = new Collection(); } - $chunk[] = $iterator->current(); - $previous = $iterator->current(); + $chunk[$iterator->key()] = $iterator->current(); $iterator->next(); } - yield new static($chunk); + if ($chunk->isNotEmpty()) { + yield new static($chunk); + } }); } diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index aae8e7c4df76..9fcf89798c4f 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -1650,15 +1650,15 @@ public function testChunkWhenGivenLessThanZero($collection) public function testChunkWhileOnEqualElements($collection) { $data = (new $collection(['A', 'A', 'B', 'B', 'C', 'C', 'C'])) - ->chunkWhile(function ($previous, $current) { - return $previous === $current; + ->chunkWhile(function ($current, $key, $chunk) { + return $chunk->last() === $current; }); $this->assertInstanceOf($collection, $data); $this->assertInstanceOf($collection, $data->first()); - $this->assertEquals(['A', 'A'], $data->first()->toArray()); - $this->assertEquals(['B', 'B'], $data->get(1)->toArray()); - $this->assertEquals(['C', 'C', 'C'], $data->last()->toArray()); + $this->assertEquals([0 => 'A', 1 => 'A'], $data->first()->toArray()); + $this->assertEquals([2 => 'B', 3 => 'B'], $data->get(1)->toArray()); + $this->assertEquals([4 => 'C', 5 => 'C', 6 => 'C'], $data->last()->toArray()); } /** @@ -1667,17 +1667,17 @@ public function testChunkWhileOnEqualElements($collection) public function testChunkWhileOnContiguouslyIncreasingIntegers($collection) { $data = (new $collection([1, 4, 9, 10, 11, 12, 15, 16, 19, 20, 21])) - ->chunkWhile(function ($previous, $current) { - return $previous + 1 == $current; + ->chunkWhile(function ($current, $key, $chunk) { + return $chunk->last() + 1 == $current; }); $this->assertInstanceOf($collection, $data); $this->assertInstanceOf($collection, $data->first()); - $this->assertEquals([1], $data->first()->toArray()); - $this->assertEquals([4], $data->get(1)->toArray()); - $this->assertEquals([9, 10, 11, 12], $data->get(2)->toArray()); - $this->assertEquals([15, 16], $data->get(3)->toArray()); - $this->assertEquals([19, 20, 21], $data->last()->toArray()); + $this->assertEquals([0 => 1], $data->first()->toArray()); + $this->assertEquals([1 => 4], $data->get(1)->toArray()); + $this->assertEquals([2 => 9, 3 => 10, 4 => 11, 5 => 12], $data->get(2)->toArray()); + $this->assertEquals([6 => 15, 7 => 16], $data->get(3)->toArray()); + $this->assertEquals([8 => 19, 9 => 20, 10 => 21], $data->last()->toArray()); } /** diff --git a/tests/Support/SupportLazyCollectionIsLazyTest.php b/tests/Support/SupportLazyCollectionIsLazyTest.php index f02fe046116a..1abaa0146f36 100644 --- a/tests/Support/SupportLazyCollectionIsLazyTest.php +++ b/tests/Support/SupportLazyCollectionIsLazyTest.php @@ -29,6 +29,23 @@ public function testChunkIsLazy() }); } + public function testChunkWhileIsLazy() + { + $collection = LazyCollection::make(['A', 'A', 'B', 'B', 'C', 'C', 'C']); + + $this->assertDoesNotEnumerateCollection($collection, function ($collection) { + $collection->chunkWhile(function ($current, $key, $chunk) { + return $current === $chunk->last(); + }); + }); + + $this->assertEnumeratesCollection($collection, 7, function ($collection) { + $collection->chunkWhile(function ($current, $key, $chunk) { + return $current === $chunk->last(); + })->take(7)->all(); + }); + } + public function testCollapseIsLazy() { $collection = LazyCollection::make([