Skip to content

Commit

Permalink
Add Transpose operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Jun 7, 2020
1 parent 9cc7798 commit 0070b45
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 3 deletions.
7 changes: 4 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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:
Expand Down
38 changes: 38 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
~~~~~

Expand Down Expand Up @@ -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
Expand Down
54 changes: 54 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
9 changes: 9 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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}
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -114,6 +115,7 @@ interface Collection extends
Splitable,
Tailable,
Timesable,
Transposeable,
Untilable,
Walkable,
Windowable,
Expand Down
20 changes: 20 additions & 0 deletions src/Contract/Operation/Transposeable.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\Base;

/**
* Interface Transposeable.
*/
interface Transposeable
{
/**
* Matrix transposition.
*
* @return \loophp\collection\Base<mixed>|\loophp\collection\Contract\Collection<mixed>
*/
public function transpose(): Base;
}
35 changes: 35 additions & 0 deletions src/Operation/Transpose.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Generator;
use loophp\collection\Contract\Operation;
use loophp\collection\Iterator\IterableIterator;
use MultipleIterator;

/**
* Class Transpose.
*/
final class Transpose implements Operation
{
/**
* {@inheritdoc}
*/
public function __invoke(): Closure
{
return static function (iterable $collection): Generator {
$mit = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);

foreach ($collection as $collectionItem) {
$mit->attachIterator(new IterableIterator($collectionItem));
}

foreach ($mit as $key => $value) {
yield current($key) => $value;
}
};
}
}

0 comments on commit 0070b45

Please sign in to comment.