Skip to content

Commit

Permalink
Add Unzip operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 7, 2020
1 parent c9e6701 commit cad956f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 6 deletions.
18 changes: 18 additions & 0 deletions docs/pages/api.rst
Expand Up @@ -1527,6 +1527,23 @@ Signature: ``Collection::unwrap();``
$collection = Collection::with($data)
->unwrap();
unzip
~~~~~

Unzip a collection.

Interface: `Unzipable`_

Signature: ``Collection::unzip();``

.. code-block:: php
$a = Collection::with(['a' => 'a', 'b' => 'b', 'c' => 'c'])
->zip(['d', 'e', 'f', 'g'], [1, 2, 3, 4, 5]);
$b = Collection::with($a)
->unzip(); // [ ['a','b','c',null,null], ['d','e','f','g',null], [1,2,3,4,5] ]
window
~~~~~~

Expand Down Expand Up @@ -1653,6 +1670,7 @@ Signature: ``Collection::zip(iterable ...$iterables);``
.. _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
.. _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
.. _Wrapable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Wrapable.php
.. _Zipable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Zipable.php
27 changes: 21 additions & 6 deletions spec/loophp/collection/CollectionSpec.php
Expand Up @@ -2016,6 +2016,24 @@ public function it_can_unwrap()
]);
}

public function it_can_unzip(): void
{
$this::fromIterable(range('A', 'C'))
->zip(['D', 'E', 'F', 'G'], [1, 2, 3, 4, 5])
->unzip()
->shouldIterateAs([
[
'A', 'B', 'C', null, null,
],
[
'D', 'E', 'F', 'G', null,
],
[
1, 2, 3, 4, 5,
],
]);
}

public function it_can_use_range(): void
{
$this::range(0, 5)
Expand Down Expand Up @@ -2291,20 +2309,17 @@ public function it_can_zip(): void
{
$this::fromIterable(range('A', 'C'))
->zip(['D', 'E', 'F'])
->all()
->shouldReturn([['A', 'D'], ['B', 'E'], ['C', 'F']]);
->shouldIterateAs([['A', 'D'], ['B', 'E'], ['C', 'F']]);

$this::fromIterable(['A', 'C', 'E'])
->zip(['B', 'D', 'F', 'H'])
->all()
->shouldReturn([['A', 'B'], ['C', 'D'], ['E', 'F'], [null, 'H']]);
->shouldIterateAs([['A', 'B'], ['C', 'D'], ['E', 'F'], [null, 'H']]);

$collection = Collection::fromIterable(range(1, 5));

$this::fromIterable($collection)
->zip(range('A', 'E'))
->all()
->shouldReturn([[1, 'A'], [2, 'B'], [3, 'C'], [4, 'D'], [5, 'E']]);
->shouldIterateAs([[1, 'A'], [2, 'B'], [3, 'C'], [4, 'D'], [5, 'E']]);
}

public function it_is_initializable(): void
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Expand Up @@ -92,6 +92,7 @@
use loophp\collection\Operation\Unpair;
use loophp\collection\Operation\Until;
use loophp\collection\Operation\Unwrap;
use loophp\collection\Operation\Unzip;
use loophp\collection\Operation\Window;
use loophp\collection\Operation\Wrap;
use loophp\collection\Operation\Zip;
Expand Down Expand Up @@ -731,6 +732,11 @@ public function unwrap(): CollectionInterface
return $this->run(Unwrap::of());
}

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

public function window(int ...$length): CollectionInterface
{
return $this->run(Window::of()(...$length));
Expand Down
3 changes: 3 additions & 0 deletions src/Contract/Collection.php
Expand Up @@ -85,6 +85,7 @@
use loophp\collection\Contract\Operation\Unpairable;
use loophp\collection\Contract\Operation\Untilable;
use loophp\collection\Contract\Operation\Unwrapable;
use loophp\collection\Contract\Operation\Unzipable;
use loophp\collection\Contract\Operation\Windowable;
use loophp\collection\Contract\Operation\Wrapable;
use loophp\collection\Contract\Operation\Zipable;
Expand Down Expand Up @@ -166,6 +167,7 @@
* @template-extends Unpairable<TKey, T>
* @template-extends Untilable<TKey, T>
* @template-extends Unwrapable<TKey, T>
* @template-extends Unzipable<TKey, T>
* @template-extends Windowable<TKey, T>
* @template-extends Wrapable<TKey, T>
* @template-extends Zipable<TKey, T>
Expand Down Expand Up @@ -253,6 +255,7 @@ interface Collection extends
Unpairable,
Untilable,
Unwrapable,
Unzipable,
Windowable,
Wrapable,
Zipable
Expand Down
20 changes: 20 additions & 0 deletions src/Contract/Operation/Unzipable.php
@@ -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 Unzipable
{
/**
* @return \loophp\collection\Contract\Collection<TKey,T>
*/
public function unzip(): Collection;
}
44 changes: 44 additions & 0 deletions src/Operation/Unzip.php
@@ -0,0 +1,44 @@
<?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 Unzip extends AbstractOperation
{
/**
* @psalm-return Closure(Iterator<TKey, list<T>>): Generator<int, list<T>>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param Iterator<TKey, list<T>> $iterator
*
* @psalm-return Generator<int, list<T>>
*/
static function (Iterator $iterator): Generator {
$index = 0;
$result = [];

foreach ($iterator as $current) {
foreach ($current as $c) {
$result[$index++][] = $c;
}

$index = 0;
}

return yield from $result;
};
}
}

0 comments on commit cad956f

Please sign in to comment.