Skip to content

Commit

Permalink
feat: Add FoldRight1 operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 20, 2020
1 parent c034101 commit 18b9b1d
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 0 deletions.
11 changes: 11 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,16 @@ Interface: `FoldRightable`_

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

foldRight1
~~~~~~~~~~

Takes the last two items of the list and applies the function, then it takes the third item from the end and the result,
and so on. See `scanRight1` for intermediate results.

Interface: `FoldRight1able`_

Signature: ``Collection::foldRight1(callable $callback);``

forget
~~~~~~

Expand Down Expand Up @@ -1711,6 +1721,7 @@ Signature: ``Collection::zip(iterable ...$iterables);``
.. _FoldLeftable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/FoldLeftable.php
.. _FoldLeft1able: https://github.com/loophp/collection/blob/master/src/Contract/Operation/FoldLeft1able.php
.. _FoldRightable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/FoldRightable.php
.. _FoldRight1able: https://github.com/loophp/collection/blob/master/src/Contract/Operation/FoldRight1able.php
.. _Forgetable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Forgetable.php
.. _Frequencyable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Frequencyable.php
.. _Getable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Getable.php
Expand Down
15 changes: 15 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,21 @@ public function it_can_foldleft1(): void
->shouldReturn(12);
}

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

$this::fromIterable([8, 12, 24, 4])
->foldRight1($callback)
->shouldReturn(4);

$this::fromIterable([12])
->foldRight1($callback)
->shouldReturn(12);
}

public function it_can_forget(): void
{
$this::fromIterable(range('A', 'E'))
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use loophp\collection\Operation\FoldLeft;
use loophp\collection\Operation\FoldLeft1;
use loophp\collection\Operation\FoldRight;
use loophp\collection\Operation\FoldRight1;
use loophp\collection\Operation\Forget;
use loophp\collection\Operation\Frequency;
use loophp\collection\Operation\Get;
Expand Down Expand Up @@ -405,6 +406,11 @@ public function foldRight(callable $callback, $initial = null)
return $this->run(Foldright::of()($callback)($initial))->getIterator()->current();
}

public function foldRight1(callable $callback)
{
return $this->run(FoldRight1::of()($callback))->getIterator()->current();
}

public function forget(...$keys): CollectionInterface
{
return $this->run(Forget::of()(...$keys));
Expand Down
3 changes: 3 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use loophp\collection\Contract\Operation\Flipable;
use loophp\collection\Contract\Operation\FoldLeft1able;
use loophp\collection\Contract\Operation\FoldLeftable;
use loophp\collection\Contract\Operation\FoldRight1able;
use loophp\collection\Contract\Operation\FoldRightable;
use loophp\collection\Contract\Operation\Forgetable;
use loophp\collection\Contract\Operation\Frequencyable;
Expand Down Expand Up @@ -124,6 +125,7 @@
* @template-extends Flipable<TKey, T>
* @template-extends FoldLeftable<TKey, T>
* @template-extends FoldLeft1able<TKey, T>
* @template-extends FoldRight1able<TKey, T>
* @template-extends Forgetable<TKey, T>
* @template-extends Frequencyable<TKey, T>
* @template-extends Getable<TKey, T>
Expand Down Expand Up @@ -204,6 +206,7 @@ interface Collection extends
Flipable,
FoldLeft1able,
FoldLeftable,
FoldRight1able,
FoldRightable,
Forgetable,
Frequencyable,
Expand Down
19 changes: 19 additions & 0 deletions src/Contract/Operation/FoldRight1able.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Contract\Operation;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*/
interface FoldRight1able
{
/**
* @return mixed
* @psalm-return T|null
*/
public function foldRight1(callable $callback);
}
49 changes: 49 additions & 0 deletions src/Operation/FoldRight1.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?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 FoldRight1 extends AbstractOperation
{
/**
* @psalm-return Closure(callable(T|null, T, TKey, Iterator<TKey, T>):(T|null)): Closure(Iterator<TKey, T>): Generator<TKey, T>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param callable(T|null, T, TKey, Iterator<TKey, T>):(T|null) $callback
*
* @psalm-return Closure(Iterator<TKey, T>): Generator<TKey, T>
*/
static function (callable $callback): Closure {
return
/**
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return Generator<TKey, T>
*/
static function (Iterator $iterator) use ($callback): Generator {
/** @psalm-var callable(Iterator<TKey, T>): Generator<TKey, T> $foldRight1 */
$foldRight1 = Compose::of()(
Reverse::of(),
FoldLeft1::of()($callback)
);

return yield from $foldRight1($iterator);
};
};
}
}

0 comments on commit 18b9b1d

Please sign in to comment.