diff --git a/docs/pages/api.rst b/docs/pages/api.rst index 1d64d9878..833a7a739 100644 --- a/docs/pages/api.rst +++ b/docs/pages/api.rst @@ -159,17 +159,8 @@ Interface: `Allable`_ Signature: ``Collection::all();`` -.. code-block:: php - - $generator = static function (): Generator { - yield 0 => 'a'; - yield 1 => 'b'; - yield 0 => 'c'; - yield 2 => 'd'; - }; - - Collection::fromIterable($generator()) - ->all(); // [0 => 'c', 1 => 'b', 2 => 'd'] +.. literalinclude:: code/operations/all.php + :language: php append ~~~~~~ diff --git a/docs/pages/code/operations/all.php b/docs/pages/code/operations/all.php new file mode 100644 index 000000000..00c601d2b --- /dev/null +++ b/docs/pages/code/operations/all.php @@ -0,0 +1,39 @@ + usage with Collection +$generator = static function (): Generator { + yield 0 => 'a'; + + yield 1 => 'b'; + + yield 0 => 'c'; + + yield 2 => 'd'; +}; + +$collection = Collection::fromIterable($generator()); +print_r($collection->all()); // [0 => 'c', 1 => 'b', 2 => 'd'] + +// Example 2 -> standalone usage +$even = static fn (int $value): bool => $value % 2 === 0; + +$piped = Pipe::of()(Filter::of()($even), All::of())(new ArrayIterator([1, 2, 3, 4])); +print_r($piped); // [2, 4] diff --git a/spec/loophp/collection/CollectionSpec.php b/spec/loophp/collection/CollectionSpec.php index 35dc731e7..6d2334a96 100644 --- a/spec/loophp/collection/CollectionSpec.php +++ b/spec/loophp/collection/CollectionSpec.php @@ -34,6 +34,32 @@ class CollectionSpec extends ObjectBehavior { + public function it_can_all(): void + { + $this::fromIterable([1, 2, 3]) + ->all() + ->shouldIterateAs([1, 2, 3]); + + $this::fromIterable(['foo' => 'f', 'bar' => 'b']) + ->all() + ->shouldIterateAs(['foo' => 'f', 'bar' => 'b']); + + $duplicateKeyGen = static function (): Generator { + yield 'a' => 1; + + yield 'b' => 2; + + yield 'a' => 3; + }; + + $this::fromIterable($duplicateKeyGen()) + ->shouldIterateAs($duplicateKeyGen()); + + $this::fromIterable($duplicateKeyGen()) + ->all() + ->shouldIterateAs(['a' => 3, 'b' => 2]); + } + public function it_can_append(): void { $generator = static function (): Generator { diff --git a/src/Collection.php b/src/Collection.php index cc277c655..0afe90d89 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -18,6 +18,7 @@ use loophp\collection\Iterator\IterableIterator; use loophp\collection\Iterator\ResourceIterator; use loophp\collection\Iterator\StringIterator; +use loophp\collection\Operation\All; use loophp\collection\Operation\Append; use loophp\collection\Operation\Apply; use loophp\collection\Operation\Associate; @@ -169,7 +170,7 @@ public function __construct(callable $callable, ...$parameters) public function all(): array { - return iterator_to_array($this->getIterator()); + return All::of()($this->getIterator()); } public function append(...$items): CollectionInterface diff --git a/src/Contract/Operation/Pipeable.php b/src/Contract/Operation/Pipeable.php index 10d65bdef..68d3a0f8d 100644 --- a/src/Contract/Operation/Pipeable.php +++ b/src/Contract/Operation/Pipeable.php @@ -9,8 +9,6 @@ namespace loophp\collection\Contract\Operation; -use Generator; -use Iterator; use loophp\collection\Contract\Collection; /** @@ -20,7 +18,7 @@ interface Pipeable { /** - * @param callable(Iterator): Generator ...$callbacks + * @param callable(iterable): iterable ...$callbacks * * @return Collection */ diff --git a/src/Operation/All.php b/src/Operation/All.php new file mode 100644 index 000000000..fd2ab8120 --- /dev/null +++ b/src/Operation/All.php @@ -0,0 +1,32 @@ +): array + */ + public function __invoke(): Closure + { + return static fn (Iterator $iterator): array => iterator_to_array($iterator); + } +} diff --git a/src/Operation/Pipe.php b/src/Operation/Pipe.php index 733d1f3d8..85b5d45e9 100644 --- a/src/Operation/Pipe.php +++ b/src/Operation/Pipe.php @@ -10,8 +10,6 @@ namespace loophp\collection\Operation; use Closure; -use Generator; -use Iterator; /** * @immutable @@ -26,31 +24,31 @@ final class Pipe extends AbstractOperation /** * @pure * - * @return Closure(...callable(Iterator):Generator):Closure(Iterator):Iterator + * @return Closure(callable(iterable): iterable ...): Closure(iterable): iterable */ public function __invoke(): Closure { return /** - * @param callable(Iterator): Generator ...$operations + * @param callable(iterable): iterable ...$operations * - * @return Closure(Iterator): Iterator + * @return Closure(iterable): iterable */ static fn (callable ...$operations): Closure => /** - * @param Iterator $iterator + * @param iterable $iterator * - * @return Iterator + * @return iterable */ - static function (Iterator $iterator) use ($operations): Iterator { + static function (iterable $iterator) use ($operations): iterable { $callback = /** - * @param Iterator $iterator - * @param callable(Iterator): Iterator $callable + * @param iterable $iterator + * @param callable(iterable): iterable $callable * - * @return Iterator + * @return iterable */ - static fn (Iterator $iterator, callable $callable): Iterator => $callable($iterator); + static fn (iterable $iterator, callable $callable): iterable => $callable($iterator); return array_reduce($operations, $callback, $iterator); };