diff --git a/docs/pages/api.rst b/docs/pages/api.rst index 11f0d5460..3d701bb73 100644 --- a/docs/pages/api.rst +++ b/docs/pages/api.rst @@ -389,6 +389,22 @@ contains Interface: `Containsable`_ +current +~~~~~~~ + +Get the value of an item in the collection given a numeric index, default index is 0. + +Interface: `Currentable`_ + +Signature: ``Collection::current(int $index = 0);`` + +.. code-block:: php + + Collection::fromIterable(['a', 'b', 'c', 'd'])->current(); // Return 'a' + Collection::fromIterable(['a', 'b', 'c', 'd'])->current(0); // Return 'a' + Collection::fromIterable(['a', 'b', 'c', 'd'])->current(1); // Return 'b' + Collection::fromIterable(['a', 'b', 'c', 'd'])->current(10); // Return null + cycle ~~~~~ @@ -1537,6 +1553,7 @@ Signature: ``Collection::zip(iterable ...$iterables);`` .. _Combineable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Combineable.php .. _Compactable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Compactable.php .. _Containsable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Containsable.php +.. _Currentable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Currentable.php .. _Cycleable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Cycleable.php .. _Diffable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Diffable.php .. _Diffkeysable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Diffkeysable.php diff --git a/spec/loophp/collection/CollectionSpec.php b/spec/loophp/collection/CollectionSpec.php index fdea4bb23..b24288493 100644 --- a/spec/loophp/collection/CollectionSpec.php +++ b/spec/loophp/collection/CollectionSpec.php @@ -785,6 +785,23 @@ public function it_can_get_an_iterator(): void ->shouldImplement(Iterator::class); } + public function it_can_get_current() + { + $input = array_combine(range('A', 'E'), range('A', 'E')); + + $this::fromIterable($input) + ->current() + ->shouldReturn('A'); + + $this::fromIterable($input) + ->current(1) + ->shouldReturn('B'); + + $this::fromIterable($input) + ->current(10) + ->shouldReturn(null); + } + public function it_can_get_items_with_only_specific_keys(): void { $this::fromIterable(range('A', 'E')) diff --git a/src/Collection.php b/src/Collection.php index 5e085b4cb..9f3ef9274 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -24,6 +24,7 @@ use loophp\collection\Operation\Compact; use loophp\collection\Operation\Compose; use loophp\collection\Operation\Contains; +use loophp\collection\Operation\Current; use loophp\collection\Operation\Cycle; use loophp\collection\Operation\Diff; use loophp\collection\Operation\DiffKeys; @@ -298,6 +299,11 @@ public function count(): int return iterator_count($this); } + public function current(int $index = 0) + { + return Current::of()($index)($this->getIterator()); + } + public function cycle(): CollectionInterface { return $this->run(Cycle::of()); diff --git a/src/Contract/Collection.php b/src/Contract/Collection.php index 655e5869a..5023c5d0a 100644 --- a/src/Contract/Collection.php +++ b/src/Contract/Collection.php @@ -18,6 +18,7 @@ use loophp\collection\Contract\Operation\Combineable; use loophp\collection\Contract\Operation\Compactable; use loophp\collection\Contract\Operation\Containsable; +use loophp\collection\Contract\Operation\Currentable; use loophp\collection\Contract\Operation\Cycleable; use loophp\collection\Contract\Operation\Diffable; use loophp\collection\Contract\Operation\Diffkeysable; @@ -179,6 +180,7 @@ interface Collection extends Combineable, Compactable, Containsable, + Currentable, Cycleable, Diffable, Diffkeysable, diff --git a/src/Contract/Operation/Currentable.php b/src/Contract/Operation/Currentable.php new file mode 100644 index 000000000..ac78f3db3 --- /dev/null +++ b/src/Contract/Operation/Currentable.php @@ -0,0 +1,18 @@ +): T + */ + public function __invoke(): Closure + { + return + /** + * @psalm-param int $index + * + * @psalm-return Closure(Iterator): T + */ + static function (int $index): Closure { + return + /** + * @psalm-param Iterator $iterator + * + * @psalm-return T + */ + static function (Iterator $iterator) use ($index) { + for ($i = 0; $i < $index; $i++, $iterator->next()) { + } + + return $iterator->current(); + }; + }; + } +}