diff --git a/src/Collection/BaseCollection.php b/src/Collection/BaseCollection.php index 36e46b7..fc9b141 100644 --- a/src/Collection/BaseCollection.php +++ b/src/Collection/BaseCollection.php @@ -223,6 +223,41 @@ abstract class BaseCollection implements CollectionInterface return null !== $index && false !== $index; } + public function clear(): void + { + $this->elements = []; + } + + public function limit(int $max, int $offset = 0): CollectionInterface + { + $result = clone $this; + + $negativeMax = $max <= 0; + $exceededMax = $max >= $this->count(); + + if ($negativeMax || $exceededMax) { + if ($negativeMax) { + $result->clear(); + } + + return $result; + } + + $iteration = -1; + + foreach ($result as $index => $element) { + $iteration++; + + if ($iteration < $offset || ($iteration >= $offset && $iteration < $max)) { + continue; + } + + unset($result[$index]); + } + + return $result; + } + public function count(): int { return count($this->elements); diff --git a/src/Contract/Collection/CollectionInterface.php b/src/Contract/Collection/CollectionInterface.php index df84414..2c5988d 100644 --- a/src/Contract/Collection/CollectionInterface.php +++ b/src/Contract/Collection/CollectionInterface.php @@ -49,4 +49,8 @@ interface CollectionInterface extends Countable, ArrayAccess, IteratorAggregate public function isLast($element): bool; public function has($element): bool; + + public function clear(): void; + + public function limit(int $max, int $offset = 0): self; } diff --git a/tests/Collection/BaseCollectionTest.php b/tests/Collection/BaseCollectionTest.php index f6ea186..5cb8259 100644 --- a/tests/Collection/BaseCollectionTest.php +++ b/tests/Collection/BaseCollectionTest.php @@ -389,6 +389,51 @@ class BaseCollectionTest extends BaseTestCase static::assertSame($expected, $collection->toArray(), $description); } + public function testClearIfIsEmpty(): void + { + self::assertCount(0, $this->emptyCollection); + $this->emptyCollection->clear(); + self::assertCount(0, $this->emptyCollection); + } + + public function testClear(): void + { + self::assertCount(4, $this->simpleCollection); + $this->simpleCollection->clear(); + self::assertCount(0, $this->simpleCollection); + } + + public function testLimitIfIsEmpty(): void + { + $result = $this->emptyCollection->limit(10); + self::assertEquals(new StringCollection(), $result); + } + + /** + * @param array $expected + * @param int $max + * + * @dataProvider provideResultOfLimitWithDefaultOffset + */ + public function testLimitWithDefaultOffset(array $expected, int $max): void + { + $result = $this->simpleCollection->limit($max); + self::assertSame($expected, $result->toArray()); + } + + /** + * @param array $expected + * @param int $max + * @param int $offset + * + * @dataProvider provideResultOfLimit + */ + public function testLimit(array $expected, int $max, int $offset): void + { + $result = $this->simpleCollection->limit($max, $offset); + self::assertSame($expected, $result->toArray()); + } + public function provideElementToAddWithInvalidType(): ?Generator { yield [ @@ -623,6 +668,94 @@ class BaseCollectionTest extends BaseTestCase ]; } + public function provideResultOfLimitWithDefaultOffset(): ?Generator + { + yield 'Negative value of maximum' => [ + [], + -1, + ]; + + yield 'Maximum set to 0' => [ + [], + 0, + ]; + + yield 'Maximum set to 1' => [ + [ + 'lorem', + ], + 1, + ]; + + yield 'Maximum greater than size of collection' => [ + [ + 'lorem', + 'ipsum', + 123 => 'dolor', + 345 => 'sit', + ], + 10, + ]; + } + + public function provideResultOfLimit(): ?Generator + { + yield 'Negative value of maximum & negative offset' => [ + [], + -1, + -2, + ]; + + yield 'Negative value of maximum & positive offset' => [ + [], + -1, + 2, + ]; + + yield 'Maximum set to 0 & negative offset' => [ + [], + 0, + -2, + ]; + + yield 'Maximum set to 0 & positive offset' => [ + [], + 0, + 2, + ]; + + yield 'Maximum set to 1 & offset smaller than size of collection' => [ + [ + 'lorem', + 'ipsum', + ], + 1, + 2, + ]; + + yield 'Maximum set to 1 & offset equal size of collection' => [ + [ + 'lorem', + 'ipsum', + 123 => 'dolor', + 345 => 'sit', + ], + 1, + 4, + ]; + + yield 'Maximum set to 1 & offset greater than size of collection' => [ + [ + 'lorem', + 'ipsum', + 123 => 'dolor', + 345 => 'sit', + ], + 1, + 10, + ]; + } + /** * {@inheritdoc} */