Skip to content

Commit

Permalink
feat: Add scanRight operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 21, 2020
1 parent 8b9aaa3 commit c01274f
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 0 deletions.
23 changes: 23 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,28 @@ Signature: ``Collection::scanLeft1(callable $callback);``
Collection::fromIterable([12])
->scanLeft1($callback); // [12]
scanRight
~~~~~~~~~

Takes the initial value and the last item of the list and applies the function, then it takes the penultimate item from
the end and the result, and so on. It returns the list of intermediate and final results.

Interface: `ScanRightable`_

Signature: ``Collection::scanRight(callable $callback, $initial = null);``

.. code-block:: php
$callback = static function ($carry, $value) {
return $value / $carry;
};
Collection::fromIterable([8, 12, 24, 4])
->scanRight($callback, 2); // [8, 1, 12, 2, 2]
Collection::empty()
->scanRight($callback, 3); // [3]
since
~~~~~

Expand Down Expand Up @@ -1806,6 +1828,7 @@ Signature: ``Collection::zip(iterable ...$iterables);``
.. _Scaleable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Scaleable.php
.. _ScanLeftable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/ScanLeftable.php
.. _ScanLeft1able: https://github.com/loophp/collection/blob/master/src/Contract/Operation/ScanLeft1able.php
.. _ScanRightable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/ScanRightable.php
.. _Sinceable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Sinceable.php
.. _Sliceable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Sliceable.php
.. _Sortable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Sortable.php
Expand Down
27 changes: 27 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,33 @@ public function it_can_scanleft1(): void
->shouldIterateAs([12]);
}

public function it_can_scanright(): void
{
$callback = static function ($carry, $value) {
return $value / $carry;
};

$result = static function () {
yield 0 => 8;

yield 1 => 1;

yield 2 => 12;

yield 3 => 2;

yield 0 => 2;
};

$this::fromIterable([8, 12, 24, 4])
->scanRight($callback, 2)
->shouldIterateAs($result());

$this::fromIterable([])
->scanRight($callback, 3)
->shouldIterateAs([3]);
}

public function it_can_shuffle(): void
{
$data = range('A', 'Z');
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
use loophp\collection\Operation\Scale;
use loophp\collection\Operation\ScanLeft;
use loophp\collection\Operation\ScanLeft1;
use loophp\collection\Operation\ScanRight;
use loophp\collection\Operation\Shuffle;
use loophp\collection\Operation\Since;
use loophp\collection\Operation\Slice;
Expand Down Expand Up @@ -688,6 +689,11 @@ public function scanLeft1(callable $callback): CollectionInterface
return $this->run(ScanLeft1::of()($callback));
}

public function scanRight(callable $callback, $initial = null): CollectionInterface
{
return $this->run(ScanRight::of()($callback)($initial));
}

public function shuffle(): CollectionInterface
{
return $this->run(Shuffle::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 @@ -73,6 +73,7 @@
use loophp\collection\Contract\Operation\Scaleable;
use loophp\collection\Contract\Operation\ScanLeft1able;
use loophp\collection\Contract\Operation\ScanLeftable;
use loophp\collection\Contract\Operation\ScanRightable;
use loophp\collection\Contract\Operation\Shuffleable;
use loophp\collection\Contract\Operation\Sinceable;
use loophp\collection\Contract\Operation\Sliceable;
Expand Down Expand Up @@ -162,6 +163,7 @@
* @template-extends Scaleable<TKey, T>
* @template-extends ScanLeft1able<TKey, T>
* @template-extends ScanLeftable<TKey, T>
* @template-extends ScanRightable<TKey, T>
* @template-extends Shuffleable<TKey, T>
* @template-extends Sinceable<TKey, T>
* @template-extends Sliceable<TKey, T>
Expand Down Expand Up @@ -251,6 +253,7 @@ interface Collection extends
Scaleable,
ScanLeft1able,
ScanLeftable,
ScanRightable,
Shuffleable,
Sinceable,
Sliceable,
Expand Down
23 changes: 23 additions & 0 deletions src/Contract/Operation/ScanRightable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?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 ScanRightable
{
/**
* @param mixed $initial
* @psalm-param T|null $initial
*
* @psalm-return \loophp\collection\Contract\Collection<TKey, T>
*/
public function scanRight(callable $callback, $initial = null): Collection;
}
54 changes: 54 additions & 0 deletions src/Operation/ScanRight.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Generator;
use Iterator;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*
* phpcs:disable Generic.Files.LineLength.TooLong
*/
final class ScanRight extends AbstractOperation
{
/**
* @psalm-return Closure(callable(T|null, T, TKey, Iterator<TKey, T>):(T|null)): Closure(T|null): Closure(Iterator<TKey, T>): Generator<int|TKey, T|null>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param callable(T|null, T, TKey, Iterator<TKey, T>):(T|null) $callback
*
* @psalm-return Closure(T|null): Closure(Iterator<TKey, T>): Generator<int|TKey, T|null>
*/
static function (callable $callback): Closure {
return
/**
* @param mixed|null $initial
* @psalm-param T|null $initial
*
* @psalm-return Closure(Iterator<TKey, T>): Generator<int|TKey, T|null>
*/
static function ($initial = null) use ($callback): Closure {
return
/**
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return Generator<int|TKey, T|null>
*/
static function (Iterator $iterator) use ($callback, $initial): Generator {
yield from Reverse::of()(Reduction::of()($callback)($initial)(Reverse::of()($iterator)));

return yield $initial;
};
};
};
}
}

0 comments on commit c01274f

Please sign in to comment.