diff --git a/docs/pages/api.rst b/docs/pages/api.rst index e184fc15b..7ab81a4c7 100644 --- a/docs/pages/api.rst +++ b/docs/pages/api.rst @@ -153,7 +153,6 @@ Signature: ``Collection::with($data = [], ...$parameters);`` // With a resource/stream $collection = Collection::with(fopen( __DIR__ . '/vendor/autoload.php', 'r')); - Methods (operations) -------------------- @@ -832,6 +831,29 @@ Signature: ``Collection::only(...$keys);`` $collection = Collection::with(range(10, 100)) ->only(3, 10, 'a', 9); +pack +~~~~ + +Wrap each items into an array containing 2 items: the key and the value. + +Interface: `Packable`_ + +Signature: ``Collection::pack();`` + +.. code-block:: php + + $input = ['a' => 'b', 'c' => 'd', 'e' => 'f']; + + $c = Collection::fromIterable($input) + ->pack(); + + // [ + // ['a', 'b'], + // ['c', 'd'], + // ['e', 'f'], + // ] + + pad ~~~ diff --git a/spec/loophp/collection/CollectionSpec.php b/spec/loophp/collection/CollectionSpec.php index b33d4bc9f..0cfce08d6 100644 --- a/spec/loophp/collection/CollectionSpec.php +++ b/spec/loophp/collection/CollectionSpec.php @@ -1312,6 +1312,30 @@ public function it_can_nullsy(): void ->shouldReturn(false); } + public function it_can_pack(): void + { + $input = array_combine(range('a', 'c'), range('a', 'c')); + + $this::fromIterable($input) + ->pack() + ->shouldIterateAs( + [ + 0 => [ + 0 => 'a', + 1 => 'a', + ], + 1 => [ + 0 => 'b', + 1 => 'b', + ], + 2 => [ + 0 => 'c', + 1 => 'c', + ], + ] + ); + } + public function it_can_pad(): void { $input = array_combine(range('A', 'E'), range('A', 'E')); diff --git a/src/Collection.php b/src/Collection.php index 31a351924..64eb800c2 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -49,6 +49,7 @@ use loophp\collection\Operation\Normalize; use loophp\collection\Operation\Nth; use loophp\collection\Operation\Only; +use loophp\collection\Operation\Pack; use loophp\collection\Operation\Pad; use loophp\collection\Operation\Pair; use loophp\collection\Operation\Permutate; @@ -512,6 +513,11 @@ public function only(...$keys): CollectionInterface return $this->run(new Only(...$keys)); } + public function pack(): CollectionInterface + { + return $this->run(new Pack()); + } + public function pad(int $size, $value): CollectionInterface { return $this->run(new Pad($size, $value)); diff --git a/src/Contract/Operation/Packable.php b/src/Contract/Operation/Packable.php new file mode 100644 index 000000000..1ca15b856 --- /dev/null +++ b/src/Contract/Operation/Packable.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 Packable +{ + /** + * @psalm-return \loophp\collection\Contract\Collection<int, array{0: TKey, 1: T}> + */ + public function pack(): Collection; +} diff --git a/src/Operation/Pack.php b/src/Operation/Pack.php new file mode 100644 index 000000000..615f78c64 --- /dev/null +++ b/src/Operation/Pack.php @@ -0,0 +1,33 @@ +<?php + +declare(strict_types=1); + +namespace loophp\collection\Operation; + +use Closure; +use Generator; +use Iterator; +use loophp\collection\Contract\Operation; + +/** + * @psalm-template TKey + * @psalm-template TKey of array-key + * @psalm-template T + */ +final class Pack extends AbstractOperation implements Operation +{ + public function __invoke(): Closure + { + return + /** + * @psalm-param Iterator<TKey, T> $iterator + * + * @psalm-return Generator<int, array{0:TKey, 1:T}> + */ + static function (Iterator $iterator): Generator { + foreach ($iterator as $key => $value) { + yield [$key, $value]; + } + }; + } +}