From 72df47a4f72da849bf74c211536e2f3e4ed913b6 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Mon, 21 Sep 2020 18:29:59 +0200 Subject: [PATCH] feat: Add Words operation. --- docs/pages/api.rst | 21 ++++++++++ spec/loophp/collection/CollectionSpec.php | 29 ++++++++++++++ src/Collection.php | 6 +++ src/Contract/Collection.php | 3 ++ src/Contract/Operation/Wordsable.php | 20 +++++++++ src/Operation/Words.php | 49 +++++++++++++++++++++++ 6 files changed, 128 insertions(+) create mode 100644 src/Contract/Operation/Wordsable.php create mode 100644 src/Operation/Words.php diff --git a/docs/pages/api.rst b/docs/pages/api.rst index 49084fbe4..e57910e80 100644 --- a/docs/pages/api.rst +++ b/docs/pages/api.rst @@ -1832,6 +1832,26 @@ Signature: ``Collection::window(int $size);`` ->window(2) ->all(); // [ ['a'], ['a', 'b'], ['b', 'c'], ['c', 'd'], ... ] +words +~~~~~ + +Get words from a string. + +Interface: `Wordsable`_ + +Signature: ``Collection::words();`` + +.. code-block:: php + + $string = <<<'EOF' + The quick brow fox jumps over the lazy dog. + + This is another sentence. + EOF; + + Collection::fromString($string) + ->words() + wrap ~~~~ @@ -1954,5 +1974,6 @@ Signature: ``Collection::zip(iterable ...$iterables);`` .. _Unwrapable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unwrapable.php .. _Unzipable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Unzipable.php .. _Windowable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Windowable.php +.. _Wordsable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Wordsable.php .. _Wrapable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Wrapable.php .. _Zipable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Zipable.php diff --git a/spec/loophp/collection/CollectionSpec.php b/spec/loophp/collection/CollectionSpec.php index b863fcab2..1c3f2d230 100644 --- a/spec/loophp/collection/CollectionSpec.php +++ b/spec/loophp/collection/CollectionSpec.php @@ -2647,6 +2647,35 @@ public function it_can_window(): void ]); } + public function it_can_words(): void + { + $string = <<<'EOF' +The quick brow fox jumps over the lazy dog. + +This is another sentence. +EOF; + + $words = [ + 0 => 'The', + 1 => 'quick', + 2 => 'brow', + 3 => 'fox', + 4 => 'jumps', + 5 => 'over', + 6 => 'the', + 7 => 'lazy', + 8 => 'dog.', + 10 => 'This', + 11 => 'is', + 12 => 'another', + 13 => 'sentence.', + ]; + + $this::fromString($string) + ->words() + ->shouldIterateAs($words); + } + public function it_can_wrap() { $this::fromIterable(['a' => 'A', 'b' => 'B', 'c' => 'C']) diff --git a/src/Collection.php b/src/Collection.php index 3f030a2d5..5bb6e73c5 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -103,6 +103,7 @@ use loophp\collection\Operation\Unwrap; use loophp\collection\Operation\Unzip; use loophp\collection\Operation\Window; +use loophp\collection\Operation\Words; use loophp\collection\Operation\Wrap; use loophp\collection\Operation\Zip; use Psr\Cache\CacheItemPoolInterface; @@ -813,6 +814,11 @@ public static function with($data = [], ...$parameters): Collection return new self($data, ...$parameters); } + public function words(): CollectionInterface + { + return $this->run(Words::of()); + } + public function wrap(): CollectionInterface { return $this->run(Wrap::of()); diff --git a/src/Contract/Collection.php b/src/Contract/Collection.php index 5a5617e66..162d8b1ed 100644 --- a/src/Contract/Collection.php +++ b/src/Contract/Collection.php @@ -96,6 +96,7 @@ use loophp\collection\Contract\Operation\Unwrapable; use loophp\collection\Contract\Operation\Unzipable; use loophp\collection\Contract\Operation\Windowable; +use loophp\collection\Contract\Operation\Wordsable; use loophp\collection\Contract\Operation\Wrapable; use loophp\collection\Contract\Operation\Zipable; use loophp\collection\Iterator\ClosureIterator; @@ -187,6 +188,7 @@ * @template-extends Unwrapable * @template-extends Unzipable * @template-extends Windowable + * @template-extends Wordsable * @template-extends Wrapable * @template-extends Zipable * @template-extends IteratorAggregate @@ -284,6 +286,7 @@ interface Collection extends Unwrapable, Unzipable, Windowable, + Wordsable, Wrapable, Zipable { diff --git a/src/Contract/Operation/Wordsable.php b/src/Contract/Operation/Wordsable.php new file mode 100644 index 000000000..058a1dfb5 --- /dev/null +++ b/src/Contract/Operation/Wordsable.php @@ -0,0 +1,20 @@ + + */ + public function words(): Collection; +} diff --git a/src/Operation/Words.php b/src/Operation/Words.php new file mode 100644 index 000000000..418eb31b2 --- /dev/null +++ b/src/Operation/Words.php @@ -0,0 +1,49 @@ +): Generator + */ + public function __invoke(): Closure + { + return + /** + * @psalm-param Iterator $iterator + * + * @psalm-return Generator + */ + static function (Iterator $iterator): Generator { + $mapCallback = static function (array $value): string { + return implode('', $value); + }; + + /** @psalm-var callable(Iterator): Generator $explode */ + $explode = Explode::of()("\t", "\n", ' '); + /** @psalm-var callable(Iterator): Generator $map */ + $map = Map::of()($mapCallback); + /** @psalm-var callable(Iterator): Generator $compact */ + $compact = Compact::of()(); + + /** @psalm-var callable(Iterator): Generator $compose */ + $compose = Compose::of()($explode, $map, $compact); + + return yield from $compose($iterator); + }; + } +}