From e2247a392972b0620d54c55c822702d4eeb4c0d2 Mon Sep 17 00:00:00 2001 From: Wendell Adriel Date: Fri, 11 Aug 2023 10:59:17 +0100 Subject: [PATCH 1/3] Create percentage Collection method --- src/Illuminate/Collections/Collection.php | 19 ++++++++++++ src/Illuminate/Collections/LazyCollection.php | 19 ++++++++++++ tests/Support/SupportCollectionTest.php | 29 +++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/Illuminate/Collections/Collection.php b/src/Illuminate/Collections/Collection.php index 90b89a821b12..25bf1220d239 100644 --- a/src/Illuminate/Collections/Collection.php +++ b/src/Illuminate/Collections/Collection.php @@ -1758,4 +1758,23 @@ public function offsetUnset($key): void { unset($this->items[$key]); } + + /** + * Calculates the percentage of items that pass a given truth test. + * + * @param (callable(TValue, TKey): bool) $callback + * @param int $precision + * @return float + */ + public function percentage(callable $callback, int $precision = 2): float + { + if ($this->isEmpty()) { + return 0; + } + + return round( + num: $this->filter($callback)->count() / $this->count() * 100, + precision: $precision + ); + } } diff --git a/src/Illuminate/Collections/LazyCollection.php b/src/Illuminate/Collections/LazyCollection.php index 0cbe33ad9e67..bce5efb35caf 100644 --- a/src/Illuminate/Collections/LazyCollection.php +++ b/src/Illuminate/Collections/LazyCollection.php @@ -1659,6 +1659,25 @@ public function count(): int return iterator_count($this->getIterator()); } + /** + * Calculates the percentage of items that pass a given truth test. + * + * @param (callable(TValue, TKey): bool) $callback + * @param int $precision + * @return float + */ + public function percentage(callable $callback, int $precision = 2): float + { + if ($this->isEmpty()) { + return 0; + } + + return round( + num: $this->filter($callback)->count() / $this->count() * 100, + precision: $precision + ); + } + /** * Make an iterator from the given source. * diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index c4e59e1237ad..612121b37549 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -5634,6 +5634,35 @@ public function testEnsureForInheritance($collection) $data->ensure(\Throwable::class); } + /** + * @dataProvider collectionClassProvider + */ + public function testPercentageWithFlatCollection($collection) + { + $collection = new $collection([1, 1, 2, 2, 2, 3]); + + $this->assertSame(33.33, $collection->percentage(fn ($value) => $value === 1)); + $this->assertSame(50.00, $collection->percentage(fn ($value) => $value === 2)); + $this->assertSame(16.67, $collection->percentage(fn ($value) => $value === 3)); + } + + /** + * @dataProvider collectionClassProvider + */ + public function testPercentageWithNestedCollection($collection) + { + $collection = new $collection([ + ['name' => 'Taylor', 'foo' => 'foo'], + ['name' => 'Nuno', 'foo' => 'bar'], + ['name' => 'Dries', 'foo' => 'bar'], + ['name' => 'Jess', 'foo' => 'baz'], + ]); + + $this->assertSame(25.00, $collection->percentage(fn ($value) => $value['foo'] === 'foo')); + $this->assertSame(50.00, $collection->percentage(fn ($value) => $value['foo'] === 'bar')); + $this->assertSame(25.00, $collection->percentage(fn ($value) => $value['foo'] === 'baz')); + } + /** * Provides each collection class, respectively. * From 5af12e198e396cc9668ec5c23ff2f2f042a0448c Mon Sep 17 00:00:00 2001 From: Wendell Adriel Date: Fri, 11 Aug 2023 13:14:30 +0100 Subject: [PATCH 2/3] Update percentage to return null for empty collections and add more test cases --- src/Illuminate/Collections/Collection.php | 6 +++--- src/Illuminate/Collections/LazyCollection.php | 6 +++--- tests/Support/SupportCollectionTest.php | 12 ++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Illuminate/Collections/Collection.php b/src/Illuminate/Collections/Collection.php index 25bf1220d239..a03fee5dd119 100644 --- a/src/Illuminate/Collections/Collection.php +++ b/src/Illuminate/Collections/Collection.php @@ -1764,12 +1764,12 @@ public function offsetUnset($key): void * * @param (callable(TValue, TKey): bool) $callback * @param int $precision - * @return float + * @return float|null */ - public function percentage(callable $callback, int $precision = 2): float + public function percentage(callable $callback, int $precision = 2): float|null { if ($this->isEmpty()) { - return 0; + return null; } return round( diff --git a/src/Illuminate/Collections/LazyCollection.php b/src/Illuminate/Collections/LazyCollection.php index bce5efb35caf..8932534c7267 100644 --- a/src/Illuminate/Collections/LazyCollection.php +++ b/src/Illuminate/Collections/LazyCollection.php @@ -1664,12 +1664,12 @@ public function count(): int * * @param (callable(TValue, TKey): bool) $callback * @param int $precision - * @return float + * @return float|null */ - public function percentage(callable $callback, int $precision = 2): float + public function percentage(callable $callback, int $precision = 2): float|null { if ($this->isEmpty()) { - return 0; + return null; } return round( diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index 612121b37549..e52888d7ad30 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -5644,6 +5644,7 @@ public function testPercentageWithFlatCollection($collection) $this->assertSame(33.33, $collection->percentage(fn ($value) => $value === 1)); $this->assertSame(50.00, $collection->percentage(fn ($value) => $value === 2)); $this->assertSame(16.67, $collection->percentage(fn ($value) => $value === 3)); + $this->assertSame(0.0, $collection->percentage(fn ($value) => $value === 5)); } /** @@ -5661,6 +5662,17 @@ public function testPercentageWithNestedCollection($collection) $this->assertSame(25.00, $collection->percentage(fn ($value) => $value['foo'] === 'foo')); $this->assertSame(50.00, $collection->percentage(fn ($value) => $value['foo'] === 'bar')); $this->assertSame(25.00, $collection->percentage(fn ($value) => $value['foo'] === 'baz')); + $this->assertSame(0.0, $collection->percentage(fn ($value) => $value['foo'] === 'test')); + } + + /** + * @dataProvider collectionClassProvider + */ + public function testPercentageReturnsNullForEmptyCollections($collection) + { + $collection = new $collection([]); + + $this->assertNull($collection->percentage(fn ($value) => $value === 1)); } /** From c980273fe436ca8147859d77d3a90592269aad7e Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 11 Aug 2023 09:45:07 -0500 Subject: [PATCH 3/3] formatting --- src/Illuminate/Collections/Collection.php | 19 ------------------- src/Illuminate/Collections/LazyCollection.php | 19 ------------------- .../Collections/Traits/EnumeratesValues.php | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/src/Illuminate/Collections/Collection.php b/src/Illuminate/Collections/Collection.php index a03fee5dd119..90b89a821b12 100644 --- a/src/Illuminate/Collections/Collection.php +++ b/src/Illuminate/Collections/Collection.php @@ -1758,23 +1758,4 @@ public function offsetUnset($key): void { unset($this->items[$key]); } - - /** - * Calculates the percentage of items that pass a given truth test. - * - * @param (callable(TValue, TKey): bool) $callback - * @param int $precision - * @return float|null - */ - public function percentage(callable $callback, int $precision = 2): float|null - { - if ($this->isEmpty()) { - return null; - } - - return round( - num: $this->filter($callback)->count() / $this->count() * 100, - precision: $precision - ); - } } diff --git a/src/Illuminate/Collections/LazyCollection.php b/src/Illuminate/Collections/LazyCollection.php index 8932534c7267..0cbe33ad9e67 100644 --- a/src/Illuminate/Collections/LazyCollection.php +++ b/src/Illuminate/Collections/LazyCollection.php @@ -1659,25 +1659,6 @@ public function count(): int return iterator_count($this->getIterator()); } - /** - * Calculates the percentage of items that pass a given truth test. - * - * @param (callable(TValue, TKey): bool) $callback - * @param int $precision - * @return float|null - */ - public function percentage(callable $callback, int $precision = 2): float|null - { - if ($this->isEmpty()) { - return null; - } - - return round( - num: $this->filter($callback)->count() / $this->count() * 100, - precision: $precision - ); - } - /** * Make an iterator from the given source. * diff --git a/src/Illuminate/Collections/Traits/EnumeratesValues.php b/src/Illuminate/Collections/Traits/EnumeratesValues.php index e95bdcf76ff9..f0bd10b19261 100644 --- a/src/Illuminate/Collections/Traits/EnumeratesValues.php +++ b/src/Illuminate/Collections/Traits/EnumeratesValues.php @@ -481,6 +481,25 @@ public function partition($key, $operator = null, $value = null) return new static([new static($passed), new static($failed)]); } + /** + * Calculate the percentage of items that pass a given truth test. + * + * @param (callable(TValue, TKey): bool) $callback + * @param int $precision + * @return float|null + */ + public function percentage(callable $callback, int $precision = 2) + { + if ($this->isEmpty()) { + return null; + } + + return round( + $this->filter($callback)->count() / $this->count() * 100, + $precision + ); + } + /** * Get the sum of the given values. *