From 99943b8acf667f62c90f32f5181f115a047ac8b8 Mon Sep 17 00:00:00 2001 From: redgluten Date: Tue, 25 Aug 2020 09:36:18 +0200 Subject: [PATCH 1/5] chunkWhile(): defer to lazy collection method --- src/Illuminate/Collections/Collection.php | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) 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) + ); } /** From 2f0921217623ed89db08507ee7977f5a575300f2 Mon Sep 17 00:00:00 2001 From: redgluten Date: Tue, 25 Aug 2020 09:36:46 +0200 Subject: [PATCH 2/5] chunkWhile(): preserve keys and pass whole chunk to callback --- src/Illuminate/Collections/LazyCollection.php | 19 ++++++++++++------ tests/Support/SupportCollectionTest.php | 20 +++++++++---------- 2 files changed, 23 insertions(+), 16 deletions(-) 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..8f942bcda9f6 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -1656,9 +1656,9 @@ public function testChunkWhileOnEqualElements($collection) $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()); } /** From 069fbeff571ce376886f7f2aba437575dcbd731d Mon Sep 17 00:00:00 2001 From: redgluten Date: Tue, 25 Aug 2020 09:37:03 +0200 Subject: [PATCH 3/5] chunkWhile(): ensure lazy collection is lazy --- .../Support/SupportLazyCollectionIsLazyTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/Support/SupportLazyCollectionIsLazyTest.php b/tests/Support/SupportLazyCollectionIsLazyTest.php index f02fe046116a..138b0f2f5932 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([ From c06926f6cf57183901c9d979ced8dbfa034a55d0 Mon Sep 17 00:00:00 2001 From: redgluten Date: Tue, 25 Aug 2020 09:43:08 +0200 Subject: [PATCH 4/5] =?UTF-8?q?chunkWhile():=20fix=20indenting=20?= =?UTF-8?q?=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SupportLazyCollectionIsLazyTest.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/Support/SupportLazyCollectionIsLazyTest.php b/tests/Support/SupportLazyCollectionIsLazyTest.php index 138b0f2f5932..1abaa0146f36 100644 --- a/tests/Support/SupportLazyCollectionIsLazyTest.php +++ b/tests/Support/SupportLazyCollectionIsLazyTest.php @@ -31,19 +31,19 @@ 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(); - }); + $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() From b9b1badf05c538a293ca36ce3f5c135601cddede Mon Sep 17 00:00:00 2001 From: redgluten Date: Tue, 25 Aug 2020 09:53:21 +0200 Subject: [PATCH 5/5] chunkWhile() fix Equal Elements test callback --- tests/Support/SupportCollectionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index 8f942bcda9f6..9fcf89798c4f 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -1650,8 +1650,8 @@ 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);