diff --git a/docs/index.rst b/docs/index.rst index 0a4577011..bf709e189 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,7 +7,7 @@ It's similar to `other available collection libraries`_ based on regular PHP arr but with a lazy mechanism under the hood that strives to do as little work as possible while being as flexible as possible. -Collection leverages PHP's generators and iterators to allow you to work with very large data sets while keeping memory +Collection leverages PHP generators and iterators to allow you to work with very large data sets while keeping memory usage as low as possible. For example, imagine your application needs to process a multi-gigabyte log file while taking advantage of this @@ -26,11 +26,11 @@ On top of this, this library: Except a few methods, most of methods are `pure`_ and return a new Collection object. -This library has been inspired by the `Laravel Support Package`_ and `Lazy.js`_. +This library has been inspired by the `Laravel Support Package`_, `Lazy.js`_ and `Ruby arrays`_. It uses the following `PHP Standards Recommendations`_ : -- `PSR-4`_ for classes autoloading, +- `PSR-4`_ for classes auto loading, - `PSR-12`_ for coding standards. This library is framework agnostic and can be integrated in any PHP project, in any framework. @@ -46,6 +46,7 @@ This library is framework agnostic and can be integrated in any PHP project, in .. _PHP Standards Recommendations: https://www.php-fig.org/ .. _PSR-4: https://www.php-fig.org/psr/psr-4/ .. _PSR-12: https://www.php-fig.org/psr/psr-12/ +.. _Ruby arrays: https://apidock.com/ruby/Array .. toctree:: :hidden: diff --git a/docs/pages/api.rst b/docs/pages/api.rst index a664e0401..238406782 100644 --- a/docs/pages/api.rst +++ b/docs/pages/api.rst @@ -710,6 +710,43 @@ Signature: ``Collection::tail(int $length = 1);`` $collection = Collection::with(['a', 'b', 'c']) ->tail(2); +transpose +~~~~~~~~~ + +Matrix transposition. + +Interface: `Transposeable`_ + +Signature: ``Collection::transpose();`` + +.. code-block:: php + + $records = [ + [ + 'id' => 2135, + 'first_name' => 'John', + 'last_name' => 'Doe', + ], + [ + 'id' => 3245, + 'first_name' => 'Sally', + 'last_name' => 'Smith', + ], + [ + 'id' => 5342, + 'first_name' => 'Jane', + 'last_name' => 'Jones', + ], + [ + 'id' => 5623, + 'first_name' => 'Peter', + 'last_name' => 'Doe', + ], + ]; + + $result = Collection::with($records) + ->transpose(); + until ~~~~~ @@ -827,6 +864,7 @@ Work in progress... sorry. .. _Sortable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Sortable.php .. _Splitable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Splitable.php .. _Tailable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Tailable.php +.. _Transposeable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Transposeable.php .. _Untilable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Untilable.php .. _Walkable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Walkable.php .. _Windowable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Windowable.php diff --git a/spec/loophp/collection/CollectionSpec.php b/spec/loophp/collection/CollectionSpec.php index 8c2ced0d7..2dc58996a 100644 --- a/spec/loophp/collection/CollectionSpec.php +++ b/spec/loophp/collection/CollectionSpec.php @@ -1276,6 +1276,60 @@ public function it_can_tail(): void ->shouldIterateAs([3 => 'd', 4 => 'a']); } + public function it_can_transpose(): void + { + $records = [ + [ + 'id' => 2135, + 'first_name' => 'John', + 'last_name' => 'Doe', + ], + [ + 'id' => 3245, + 'first_name' => 'Sally', + 'last_name' => 'Smith', + ], + [ + 'id' => 5342, + 'first_name' => 'Jane', + 'last_name' => 'Jones', + ], + [ + 'id' => 5623, + 'first_name' => 'Peter', + 'last_name' => 'Doe', + ], + ]; + + $this + ->beConstructedThrough('with', [$records]); + + $this + ->transpose() + ->shouldIterateAs( + [ + 'id' => [ + 0 => 2135, + 1 => 3245, + 2 => 5342, + 3 => 5623, + ], + 'first_name' => [ + 0 => 'John', + 1 => 'Sally', + 2 => 'Jane', + 3 => 'Peter', + ], + 'last_name' => [ + 0 => 'Doe', + 1 => 'Smith', + 2 => 'Jones', + 3 => 'Doe', + ], + ] + ); + } + public function it_can_until(): void { $collatz = static function (int $initial = 1): int { diff --git a/src/Collection.php b/src/Collection.php index df9219c3e..31f094d5d 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -46,6 +46,7 @@ use loophp\collection\Operation\Split; use loophp\collection\Operation\Tail; use loophp\collection\Operation\Times; +use loophp\collection\Operation\Transpose; use loophp\collection\Operation\Until; use loophp\collection\Operation\Walk; use loophp\collection\Operation\Window; @@ -490,6 +491,14 @@ public static function times($number = INF, ?callable $callback = null): BaseInt return (new self())->run(new Times($number, $callback)); } + /** + * {@inheritdoc} + */ + public function transpose(): BaseInterface + { + return $this->run(new Transpose()); + } + /** * {@inheritdoc} */ diff --git a/src/Contract/Collection.php b/src/Contract/Collection.php index 02dfc3009..800cdf46e 100644 --- a/src/Contract/Collection.php +++ b/src/Contract/Collection.php @@ -45,6 +45,7 @@ use loophp\collection\Contract\Operation\Splitable; use loophp\collection\Contract\Operation\Tailable; use loophp\collection\Contract\Operation\Timesable; +use loophp\collection\Contract\Operation\Transposeable; use loophp\collection\Contract\Operation\Untilable; use loophp\collection\Contract\Operation\Walkable; use loophp\collection\Contract\Operation\Windowable; @@ -114,6 +115,7 @@ interface Collection extends Splitable, Tailable, Timesable, + Transposeable, Untilable, Walkable, Windowable, diff --git a/src/Contract/Operation/Transposeable.php b/src/Contract/Operation/Transposeable.php new file mode 100644 index 000000000..2ba248a67 --- /dev/null +++ b/src/Contract/Operation/Transposeable.php @@ -0,0 +1,20 @@ +|\loophp\collection\Contract\Collection + */ + public function transpose(): Base; +} diff --git a/src/Operation/Transpose.php b/src/Operation/Transpose.php new file mode 100644 index 000000000..6a2c68013 --- /dev/null +++ b/src/Operation/Transpose.php @@ -0,0 +1,35 @@ +attachIterator(new IterableIterator($collectionItem)); + } + + foreach ($mit as $key => $value) { + yield current($key) => $value; + } + }; + } +}