Skip to content

Commit

Permalink
feat: Add Unwindow operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 16, 2020
1 parent 59f108f commit e240e6a
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 0 deletions.
26 changes: 26 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,31 @@ Signature: ``Collection::until(callable ...$callbacks);``
return 1 === $number;
});
unwindow
~~~~~~~~

Contrary of ``Collection::window()``, usually needed after a call to that operation.

Interface: `Unwindowable`_

Signature: ``Collection::unwindow();``

.. code-block:: php
// Drop all the items before finding five 9 in a row.
$input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 1, 2, 3, 4, 5, 6, 7, 8];
Collection::fromIterable($input)
->window(4)
->dropWhile(
static function (array $value): bool {
return $value !== [9, 9, 9, 9, 9];
}
)
->unwindow()
->drop(1)
->normalize(); // [1, 2, 3, 4, 5, 6, 7, 8]
unwrap
~~~~~~

Expand Down Expand Up @@ -1707,6 +1732,7 @@ Signature: ``Collection::zip(iterable ...$iterables);``
.. _Unpackable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unpackagle.php
.. _Unpairable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unpairable.php
.. _Untilable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Untilable.php
.. _Unwindowable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unwindowable.php
.. _Unwrapable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unwrapable.php
.. _Unzipable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unzipable.php
.. _Windowable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Windowable.php
Expand Down
135 changes: 135 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -2021,6 +2021,141 @@ public function it_can_until(): void
]);
}

public function it_can_unwindow(): void
{
$this::fromIterable([
0 => [
0 => 'a',
],
1 => [
0 => 'a',
1 => 'b',
],
2 => [
0 => 'a',
1 => 'b',
2 => 'c',
],
3 => [
0 => 'b',
1 => 'c',
2 => 'd',
],
4 => [
0 => 'c',
1 => 'd',
2 => 'e',
],
5 => [
0 => 'd',
1 => 'e',
2 => 'f',
],
6 => [
0 => 'e',
1 => 'f',
2 => 'g',
],
7 => [
0 => 'f',
1 => 'g',
2 => 'h',
],
8 => [
0 => 'g',
1 => 'h',
2 => 'i',
],
9 => [
0 => 'h',
1 => 'i',
2 => 'j',
],
10 => [
0 => 'i',
1 => 'j',
2 => 'k',
],
11 => [
0 => 'j',
1 => 'k',
2 => 'l',
],
12 => [
0 => 'k',
1 => 'l',
2 => 'm',
],
13 => [
0 => 'l',
1 => 'm',
2 => 'n',
],
14 => [
0 => 'm',
1 => 'n',
2 => 'o',
],
15 => [
0 => 'n',
1 => 'o',
2 => 'p',
],
16 => [
0 => 'o',
1 => 'p',
2 => 'q',
],
17 => [
0 => 'p',
1 => 'q',
2 => 'r',
],
18 => [
0 => 'q',
1 => 'r',
2 => 's',
],
19 => [
0 => 'r',
1 => 's',
2 => 't',
],
20 => [
0 => 's',
1 => 't',
2 => 'u',
],
21 => [
0 => 't',
1 => 'u',
2 => 'v',
],
22 => [
0 => 'u',
1 => 'v',
2 => 'w',
],
23 => [
0 => 'v',
1 => 'w',
2 => 'x',
],
24 => [
0 => 'w',
1 => 'x',
2 => 'y',
],
25 => [
0 => 'x',
1 => 'y',
2 => 'z',
],
])
->unwindow()
->shouldIterateAs(range('a', 'z'));
}

public function it_can_unwrap()
{
$this::fromIterable([['a' => 'A'], ['b' => 'B'], ['c' => 'C']])
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\Unpack;
use loophp\collection\Operation\Unpair;
use loophp\collection\Operation\Until;
use loophp\collection\Operation\Unwindow;
use loophp\collection\Operation\Unwrap;
use loophp\collection\Operation\Unzip;
use loophp\collection\Operation\Window;
Expand Down Expand Up @@ -733,6 +734,11 @@ public function until(callable ...$callbacks): CollectionInterface
return $this->run(Until::of()(...$callbacks));
}

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

public function unwrap(): CollectionInterface
{
return $this->run(Unwrap::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 @@ -83,6 +83,7 @@
use loophp\collection\Contract\Operation\Unpackable;
use loophp\collection\Contract\Operation\Unpairable;
use loophp\collection\Contract\Operation\Untilable;
use loophp\collection\Contract\Operation\Unwindowable;
use loophp\collection\Contract\Operation\Unwrapable;
use loophp\collection\Contract\Operation\Unzipable;
use loophp\collection\Contract\Operation\Windowable;
Expand Down Expand Up @@ -165,6 +166,7 @@
* @template-extends Unpackable<TKey, T>
* @template-extends Unpairable<TKey, T>
* @template-extends Untilable<TKey, T>
* @template-extends Unwindowable<TKey, T>
* @template-extends Unwrapable<TKey, T>
* @template-extends Unzipable<TKey, T>
* @template-extends Windowable<TKey, T>
Expand Down Expand Up @@ -252,6 +254,7 @@ interface Collection extends
Unpackable,
Unpairable,
Untilable,
Unwindowable,
Unwrapable,
Unzipable,
Windowable,
Expand Down
20 changes: 20 additions & 0 deletions src/Contract/Operation/Unwindowable.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 Unwindowable
{
/**
* @psalm-return \loophp\collection\Contract\Collection<TKey, T>
*/
public function unwindow(): Collection;
}
39 changes: 39 additions & 0 deletions src/Operation/Unwindow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Generator;
use Iterator;
use loophp\collection\Iterator\IterableIterator;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*/
final class Unwindow extends AbstractOperation
{
/**
* @psalm-return Closure(Iterator<TKey, list<T>>): Generator<TKey, T>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param Iterator<TKey, list<T>> $iterator
*
* @psalm-return Generator<TKey, T>
*/
static function (Iterator $iterator): Generator {
foreach ($iterator as $key => $value) {
/** @psalm-var Iterator<int, T> $lastIterator */
$lastIterator = Last::of()(new IterableIterator($value));

yield $key => $lastIterator->current();
}
};
}
}

0 comments on commit e240e6a

Please sign in to comment.