Skip to content

Commit

Permalink
Add Unpack operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Aug 26, 2020
1 parent 412734c commit 54a3e97
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 1 deletion.
26 changes: 25 additions & 1 deletion docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,28 @@ Signature: ``Collection::transpose();``
$result = Collection::with($records)
->transpose();
unpack
~~~~~~

Unpack items.

Interface: `Unpackable`_

Signature: ``Collection::unpack();``

.. code-block:: php
$input = [['a', 'b'], ['c', 'd'], ['e', 'f']];
$c = Collection::fromIterable($input)
->unpack();
// [
// ['a' => 'b'],
// ['c' => 'd'],
// ['e' => 'f'],
// ];
unpair
~~~~~~

Expand Down Expand Up @@ -1508,6 +1530,7 @@ Interface: `Truthyable`_
.. _Nthable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Nthable.php
.. _Nullsyable: https://github.com/loophp/collection/blob/master/src/Contract/Transformation/Nullsyable.php
.. _Onlyable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Onlyable.php
.. _Packable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Packable.php
.. _Padable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Padable.php
.. _Pairable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Pairable.php
.. _Permutateable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Permutateable.php
Expand All @@ -1529,7 +1552,8 @@ Interface: `Truthyable`_
.. _Transformable: https://github.com/loophp/collection/blob/master/src/Contract/Transformation/Transformable.php
.. _Transposeable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Transposeable.php
.. _Truthyable: https://github.com/loophp/collection/blob/master/src/Contract/Transformation/Truthyable.php
.. _Unpair: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unpairable.php
.. _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
.. _Unwrapable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unwrapable.php
.. _Windowable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Windowable.php
Expand Down
39 changes: 39 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,45 @@ public function it_can_truthy(): void
->shouldReturn(false);
}

public function it_can_unpack(): void
{
$input = [
['a', 'a'],
['b', 'b'],
['c', 'c'],
['d', 'd'],
['e', 'e'],
'bar',
];

$this::fromIterable($input)
->unpack()
->shouldIterateAs([
'a' => 'a',
'b' => 'b',
'c' => 'c',
'd' => 'd',
'e' => 'e',
]);

$input = [
['a', 'b', 'c' => 'c', 'd' => 'd'],
['e', 'f', 'g' => 'g', 'h' => 'h'],
['i', 'j'],
'foo',
];

$this::fromIterable($input)
->unpack()
->shouldIterateAs([
'a' => 'b',
'c' => 'd',
'e' => 'f',
'g' => 'h',
'i' => 'j',
]);
}

public function it_can_unpair(): void
{
$input = [
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
use loophp\collection\Operation\Tail;
use loophp\collection\Operation\Times;
use loophp\collection\Operation\Transpose;
use loophp\collection\Operation\Unpack;
use loophp\collection\Operation\Unpair;
use loophp\collection\Operation\Until;
use loophp\collection\Operation\Unwrap;
Expand Down Expand Up @@ -648,6 +649,11 @@ public function truthy(): bool
return $this->transform(new Truthy());
}

public function unpack(): CollectionInterface
{
return $this->run(new Unpack());
}

public function unpair(): CollectionInterface
{
return $this->run(new Unpair());
Expand Down
20 changes: 20 additions & 0 deletions src/Contract/Operation/Unpackable.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 Unpackable
{
/**
* @return \loophp\collection\Contract\Collection<TKey, T>
*/
public function unpack(): Collection;
}
44 changes: 44 additions & 0 deletions src/Operation/Unpack.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Generator;
use Iterator;
use loophp\collection\Contract\Operation;
use loophp\collection\Iterator\IterableIterator;
use loophp\collection\Transformation\Run;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*/
final class Unpack extends AbstractOperation implements Operation
{
public function __invoke(): Closure
{
return
/**
* @psalm-param Iterator<int, array{0:TKey, 1:T}|T> $iterator
*
* @psalm-return Generator<TKey, T>
*/
static function (Iterator $iterator): Generator {
foreach ($iterator as $key => $value) {
if (!is_iterable($value)) {
continue;
}

/** @psalm-var array<int, array<TKey, T>> $chunks */
$chunks = (new Run((new Chunk(2))))(new IterableIterator($value));

foreach ($chunks as [$k, $v]) {
yield $k => $v;
}
}
};
}
}

0 comments on commit 54a3e97

Please sign in to comment.