From 9260c4d05da37d67a69075858f41a6e7fff43743 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Wed, 12 Apr 2023 15:45:27 +0900 Subject: [PATCH] Add flatten(), a readable shortcut for unpack() (#114) --- README.md | 25 +++++++++++++++---------- src/Standard.php | 18 +++++++++++++++--- tests/UnpackTest.php | 12 ++++++++++++ 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 113aa3b..bf83192 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,8 @@ All entry points always return an instance of the pipeline. | `prepend()` | Appends the contents of an interable to the end of the pipeline. | `array_merge` | | `unshift()` | Prepends the pipeline with a list of values. | `array_unshift` | | `zip()` | Takes a number of iterables, transposing them together with the current sequence, if any. | `array_map(null, ...$array)`, Python's `zip()`, transposition | -| `unpack()` | Unpacks arrays into arguments for a callback. Flattens inputs if no callback provided. | `flat_map`, `flatten` | +| `flatten()` | Flattens inputs: `[[1, 2], [3, 4]]` becomes `[1, 2, 3, 4]`. | `flat_map`, `flatten`, `collect_concat` | +| `unpack()` | Unpacks arrays into arguments for a callback. Flattens inputs if no callback provided. | | | `chunk()` | Chunks the pipeline into arrays of specified length. | `array_chunk` | | `filter()` | Removes elements unless a callback returns true. Removes falsey values if no callback provided. | `array_filter`, `Where` | | `slice()` | Extracts a slice from the inputs. Keys are not discarded intentionally. Suppors negative values for both arguments. | `array_slice` | @@ -242,6 +243,18 @@ $pipeline->map(function () { }); ``` +## `$pipeline->flatten()` + +Flatten inputs: + +```php +$pipeline->map(function () { + yield [1]; + yield [2, 3]; +})->unpack()->toArray(); +// [1, 2, 3] +``` + ## `$pipeline->unpack()` An extra variant of `map` which unpacks arrays into arguments for a callback. @@ -269,15 +282,7 @@ $pipeline->unpack(function ($a, array $b, \DateTime ...$dates) { You can have all kinds of standard type checks with ease too. -With no callback, the default callback for `unpack()` will flatten inputs: - -```php -$pipeline->map(function () { - yield [1]; - yield [2, 3]; -})->unpack()->toArray(); -// [1, 2, 3] -``` +With no callback, the default callback for `unpack()` will flatten inputs as in `flatten()`. ## `$pipeline->cast()` diff --git a/src/Standard.php b/src/Standard.php index 243192b..f3302a6 100644 --- a/src/Standard.php +++ b/src/Standard.php @@ -195,6 +195,18 @@ private static function joinYield(iterable $left, iterable $right): iterable yield from $right; } + /** + * Flattens inputs: arrays become lists. + * + * @return $this + */ + public function flatten(): self + { + return $this->map(static function (iterable $args = []) { + yield from $args; + }); + } + /** * An extra variant of `map` which unpacks arrays into arguments. Flattens inputs if no callback provided. * @@ -204,9 +216,9 @@ private static function joinYield(iterable $left, iterable $right): iterable */ public function unpack(?callable $func = null): self { - $func = $func ?? static function (...$args) { - yield from $args; - }; + if (null === $func) { + return $this->flatten(); + } return $this->map(static function (iterable $args = []) use ($func) { /** @psalm-suppress InvalidArgument */ diff --git a/tests/UnpackTest.php b/tests/UnpackTest.php index ac5c7a1..458354e 100644 --- a/tests/UnpackTest.php +++ b/tests/UnpackTest.php @@ -81,4 +81,16 @@ public function testWithIterator(): void [3], ])->unpack()->toArray()); } + + /** + * @covers \Pipeline\Standard::flatten() + */ + public function testFlatten(): void + { + $this->assertSame([1, 2, 3], fromArray([ + new ArrayIterator([1]), + fromArray([2]), + [3], + ])->flatten()->toArray()); + } }