Skip to content

Commit

Permalink
feat: Add Tails operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Oct 2, 2020
1 parent ffae108 commit 1299853
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 0 deletions.
15 changes: 15 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,20 @@ Signature: ``Collection::tail();``
Collection::fromIterable(['a', 'b', 'c'])
->tail(); // [1 => 'b', 2 => 'c']
tails
~~~~~

Returns the list of initial segments of its argument list, shortest last.

Interface: `Tailsable`_

Signature: ``Collection::tails();``

.. code-block:: php
Collection::fromIterable(['a', 'b', 'c'])
->tails(); // [['a', 'b', 'c'], ['b', 'c'], ['c'], []]
takeWhile
~~~~~~~~~

Expand Down Expand Up @@ -1962,6 +1976,7 @@ Signature: ``Collection::zip(iterable ...$iterables);``
.. _Sortable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Sortable.php
.. _Splitable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Splitable.php
.. _Tailable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Tailable.php
.. _Tailsable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Tailsable.php
.. _TakeWhileable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/TakeWhileable.php
.. _Transposeable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Transposeable.php
.. _Truthyable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Truthyable.php
Expand Down
14 changes: 14 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -2021,6 +2021,20 @@ public function it_can_tail(): void
->shouldIterateAs([1 => 'B', 2 => 'C', 3 => 'D', 4 => 'E', 5 => 'F']);
}

public function it_can_tails(): void
{
$this::fromIterable(range('A', 'E'))
->tails()
->shouldIterateAs([
['A', 'B', 'C', 'D', 'E'],
[1 => 'B', 2 => 'C', 3 => 'D', 4 => 'E'],
[2 => 'C', 3 => 'D', 4 => 'E'],
[3 => 'D', 4 => 'E'],
[4 => 'E'],
[],
]);
}

public function it_can_takeWhile(): void
{
$isSmallerThanThree = static function ($value) {
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
use loophp\collection\Operation\Sort;
use loophp\collection\Operation\Split;
use loophp\collection\Operation\Tail;
use loophp\collection\Operation\Tails;
use loophp\collection\Operation\TakeWhile;
use loophp\collection\Operation\Times;
use loophp\collection\Operation\Transpose;
Expand Down Expand Up @@ -755,6 +756,11 @@ public function tail(): CollectionInterface
return $this->run(Tail::of());
}

public function tails(): CollectionInterface
{
return $this->run(Tails::of());
}

public function takeWhile(callable $callback): CollectionInterface
{
return $this->run(TakeWhile::of()($callback));
Expand Down
3 changes: 3 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
use loophp\collection\Contract\Operation\Sortable;
use loophp\collection\Contract\Operation\Splitable;
use loophp\collection\Contract\Operation\Tailable;
use loophp\collection\Contract\Operation\Tailsable;
use loophp\collection\Contract\Operation\TakeWhileable;
use loophp\collection\Contract\Operation\Timesable;
use loophp\collection\Contract\Operation\Transposeable;
Expand Down Expand Up @@ -179,6 +180,7 @@
* @template-extends Sortable<TKey, T>
* @template-extends Splitable<TKey, T>
* @template-extends Tailable<TKey, T>
* @template-extends Tailsable<TKey, T>
* @template-extends TakeWhileable<TKey, T>
* @template-extends Transposeable<TKey, T>
* @template-extends Unlinesable<TKey, T>
Expand Down Expand Up @@ -275,6 +277,7 @@ interface Collection extends
Sortable,
Splitable,
Tailable,
Tailsable,
TakeWhileable,
Timesable,
Transposeable,
Expand Down
20 changes: 20 additions & 0 deletions src/Contract/Operation/Tailsable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Contract\Operation;

use loophp\collection\Contract\Collection;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*/
interface Tailsable
{
/**
* @psalm-return \loophp\collection\Contract\Collection<TKey, T>
*/
public function tails(): Collection;
}
47 changes: 47 additions & 0 deletions src/Operation/Tails.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use ArrayIterator;
use Closure;
use Generator;
use Iterator;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*/
final class Tails extends AbstractOperation
{
/**
* @psalm-return Closure(Iterator<TKey, T>): Generator<int, array<TKey, T>, mixed, void>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return Generator<int, array<TKey, T>, mixed, void>
*/
static function (Iterator $iterator): Generator {
/** @psalm-var Iterator<int, array{0: TKey, 1: T}> */
$iterator = Pack::of()($iterator);
$data = iterator_to_array($iterator);

while ([] !== $data) {
/** @psalm-var Iterator<TKey, T> $unpack */
$unpack = Unpack::of()(new ArrayIterator($data));

yield iterator_to_array($unpack);

array_shift($data);
}

yield [];
};
}
}

0 comments on commit 1299853

Please sign in to comment.