Skip to content

Commit

Permalink
Add Key operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 7, 2020
1 parent ce83560 commit 24fa777
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 0 deletions.
17 changes: 17 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,22 @@ Signature: ``Collection::intersperse($element, int $every = 1, int $startAt = 0)
$collection = Collection::with(range('a', 'z'))
->intersperse('foo', 3);
key
~~~

Get the key of an item in the collection given a numeric index, default index is 0.

Interface: `Keyable`_

Signature: ``Collection::key(int $index = 0);``

.. code-block:: php
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(); // Return 0
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(0); // Return 0
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(1); // Return 1
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(10); // Return null
keys
~~~~

Expand Down Expand Up @@ -1546,6 +1562,7 @@ Signature: ``Collection::zip(iterable ...$iterables);``
.. _Intersectable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Intersectable.php
.. _Intersectkeysable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Intersectkeysable.php
.. _Intersperseable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Intersperseable.php
.. _Keyable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Keyable.php
.. _Keysable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Keysable.php
.. _Lastable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Lastable.php
.. _Limitable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Limitable.php
Expand Down
17 changes: 17 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,23 @@ public function it_can_get_items_with_only_specific_keys(): void
->shouldIterateAs([0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D', 4 => 'E']);
}

public function it_can_get_key()
{
$input = array_combine(range('A', 'E'), range('A', 'E'));

$this::fromIterable($input)
->key()
->shouldReturn('A');

$this::fromIterable($input)
->key(1)
->shouldReturn('B');

$this::fromIterable($input)
->key(10)
->shouldReturn(null);
}

public function it_can_get_the_first_item(): void
{
$this::fromIterable(range(1, 10))
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
use loophp\collection\Operation\IntersectKeys;
use loophp\collection\Operation\Intersperse;
use loophp\collection\Operation\Iterate;
use loophp\collection\Operation\Key;
use loophp\collection\Operation\Keys;
use loophp\collection\Operation\Last;
use loophp\collection\Operation\Limit;
Expand Down Expand Up @@ -504,6 +505,11 @@ public function jsonSerialize(): array
return $this->all();
}

public function key(int $index = 0)
{
return Key::of()($index)($this->getIterator());
}

public function keys(): CollectionInterface
{
return $this->run(Keys::of());
Expand Down
3 changes: 3 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use loophp\collection\Contract\Operation\Intersectkeysable;
use loophp\collection\Contract\Operation\Intersperseable;
use loophp\collection\Contract\Operation\Iterateable;
use loophp\collection\Contract\Operation\Keyable;
use loophp\collection\Contract\Operation\Keysable;
use loophp\collection\Contract\Operation\Lastable;
use loophp\collection\Contract\Operation\Limitable;
Expand Down Expand Up @@ -125,6 +126,7 @@
* @template-extends Intersectable<TKey, T>
* @template-extends Intersectkeysable<TKey, T>
* @template-extends Intersperseable<TKey, T>
* @template-extends Keyable<TKey, T>
* @template-extends Keysable<TKey, T>
* @template-extends Lastable<TKey, T>
* @template-extends Limitable<TKey, T>
Expand Down Expand Up @@ -204,6 +206,7 @@ interface Collection extends
Iterateable,
IteratorAggregate,
JsonSerializable,
Keyable,
Keysable,
Lastable,
Limitable,
Expand Down
18 changes: 18 additions & 0 deletions src/Contract/Operation/Keyable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Contract\Operation;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*/
interface Keyable
{
/**
* @psalm-return TKey
*/
public function key(int $index = 0);
}
43 changes: 43 additions & 0 deletions src/Operation/Key.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Iterator;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*/
final class Key extends AbstractOperation
{
/**
* @psalm-return Closure(int): Closure(Iterator<TKey, T>): TKey
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param int $index
*
* @psalm-return Closure(Iterator<TKey, T>): TKey
*/
static function (int $index): Closure {
return
/**
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return TKey
*/
static function (Iterator $iterator) use ($index) {
for ($i = 0; $i < $index; $i++, $iterator->next()) {
}

return $iterator->key();
};
};
}
}

0 comments on commit 24fa777

Please sign in to comment.