Skip to content

Commit

Permalink
feat: Add Inits operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Oct 7, 2020
1 parent 48d9620 commit 70855c3
Show file tree
Hide file tree
Showing 6 changed files with 106 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 @@ -846,6 +846,20 @@ Signature: ``Collection::init();``
Collection::fromIterable(range('a', 'e'))
->init(); // ['a', 'b', 'c', 'd']
inits
~~~~~

Returns all initial segments of the collection, shortest first.

Interface: `Initsable`_

Signature: ``Collection::inits();``

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

Expand Down Expand Up @@ -1957,6 +1971,7 @@ Signature: ``Collection::zip(iterable ...$iterables);``
.. _IfThenElseable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/IfThenElseable.php
.. _Implodeable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Implodeable.php
.. _Initable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Initable.php
.. _Initsable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Initsable.php
.. _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
Expand Down
12 changes: 12 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,18 @@ public function it_can_init(): void
]);
}

public function it_can_inits(): void
{
$this::fromIterable(range('a', 'c'))
->inits()
->shouldIterateAs([
[],
['a'],
['a', 'b'],
['a', 'b', 'c'],
]);
}

public function it_can_intersect(): void
{
$this::fromIterable(range(1, 5))
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
use loophp\collection\Operation\IfThenElse;
use loophp\collection\Operation\Implode;
use loophp\collection\Operation\Init;
use loophp\collection\Operation\Inits;
use loophp\collection\Operation\Intersect;
use loophp\collection\Operation\IntersectKeys;
use loophp\collection\Operation\Intersperse;
Expand Down Expand Up @@ -551,6 +552,11 @@ public function init(): CollectionInterface
return $this->run(Init::of());
}

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

public function intersect(...$values): CollectionInterface
{
return $this->run(Intersect::of()(...$values));
Expand Down
3 changes: 3 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
use loophp\collection\Contract\Operation\IfThenElseable;
use loophp\collection\Contract\Operation\Implodeable;
use loophp\collection\Contract\Operation\Initable;
use loophp\collection\Contract\Operation\Initsable;
use loophp\collection\Contract\Operation\Intersectable;
use loophp\collection\Contract\Operation\Intersectkeysable;
use loophp\collection\Contract\Operation\Intersperseable;
Expand Down Expand Up @@ -146,6 +147,7 @@
* @template-extends Headable<TKey, T>
* @template-extends IfThenElseable<TKey, T>
* @template-extends Initable<TKey, T>
* @template-extends Initsable<TKey, T>
* @template-extends Intersectable<TKey, T>
* @template-extends Intersectkeysable<TKey, T>
* @template-extends Intersperseable<TKey, T>
Expand Down Expand Up @@ -240,6 +242,7 @@ interface Collection extends
IfThenElseable,
Implodeable,
Initable,
Initsable,
Intersectable,
Intersectkeysable,
Intersperseable,
Expand Down
20 changes: 20 additions & 0 deletions src/Contract/Operation/Initsable.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 Initsable
{
/**
* @psalm-return \loophp\collection\Contract\Collection<TKey, T>
*/
public function inits(): Collection;
}
50 changes: 50 additions & 0 deletions src/Operation/Inits.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?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
*/
final class Inits extends AbstractOperation
{
/**
* @psalm-return Closure(Iterator<TKey, T>): Generator<int, list<T>>
*/
public function __invoke(): Closure
{
$scanLeftCallback =
/**
* @psalm-param array<TKey, T> $carry
* @psalm-param T $value
* @psalm-param TKey $key
* @psalm-param Iterator<TKey, T> $iterator
*
* @psalm-return array<TKey, T>
*
* @param mixed $value
* @param mixed $key
*/
static function (array $carry, $value, $key, Iterator $iterator): array {
$carry[$key] = $value;

return $carry;
};

/** @psalm-var Closure(Iterator<TKey, T>): Generator<int, list<T>> $inits */
$inits = Compose::of()(
ScanLeft::of()($scanLeftCallback)([]),
Normalize::of()
);

// Point free style.
return $inits;
}
}

0 comments on commit 70855c3

Please sign in to comment.