Skip to content

Commit

Permalink
feat: Add Every operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Sep 22, 2020
1 parent 47b4716 commit 8ea76af
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 0 deletions.
19 changes: 19 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,25 @@ Signature: ``Collection::duplicate();``
->distinct()
->normalize() // [0 => 'a', 1 => 'c']
every
~~~~~

This operation tests whether all elements in the collection pass the test implemented by the provided callback.

Interface: `Everyable`_

Signature: ``Collection::every(callable $callback);``

.. code-block:: php
$callback = static function ($value): bool {
return $value < 20;
};
Collection::fromIterable(range(0, 10))
->every($callback)
->current(); // true
explode
~~~~~~~

Expand Down
31 changes: 31 additions & 0 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,37 @@ public function it_can_duplicate(): void
->shouldIterateAs($result());
}

public function it_can_every(): void
{
$callback = static function ($value): bool {
return 20 > $value;
};

$this::fromIterable(range(0, 10))
->every($callback)
->shouldIterateAs([10 => true]);

$this::empty()
->every($callback)
->shouldIterateAs([0 => true]);

$this::fromIterable(range(0, 10))
->every(
static function ($value, $key, Iterator $iterator): bool {
return is_numeric($key);
}
)
->shouldIterateAs([10 => true]);

$this::fromIterable(range(0, 10))
->every(
static function ($value, $key, Iterator $iterator): bool {
return $iterator instanceof Iterator;
}
)
->shouldIterateAs([10 => true]);
}

public function it_can_explode(): void
{
$string = 'I am just a random piece of text.';
Expand Down
6 changes: 6 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use loophp\collection\Operation\Drop;
use loophp\collection\Operation\DropWhile;
use loophp\collection\Operation\Duplicate;
use loophp\collection\Operation\Every;
use loophp\collection\Operation\Explode;
use loophp\collection\Operation\Falsy;
use loophp\collection\Operation\Filter;
Expand Down Expand Up @@ -369,6 +370,11 @@ public static function empty(): Collection
return new self();
}

public function every(callable $callback): CollectionInterface
{
return $this->run(Every::of()($callback));
}

public function explode(...$explodes): CollectionInterface
{
return $this->run(Explode::of()(...$explodes));
Expand Down
3 changes: 3 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use loophp\collection\Contract\Operation\Dropable;
use loophp\collection\Contract\Operation\DropWhileable;
use loophp\collection\Contract\Operation\Duplicateable;
use loophp\collection\Contract\Operation\Everyable;
use loophp\collection\Contract\Operation\Explodeable;
use loophp\collection\Contract\Operation\Falsyable;
use loophp\collection\Contract\Operation\Filterable;
Expand Down Expand Up @@ -126,6 +127,7 @@
* @template-extends Dropable<TKey, T>
* @template-extends DropWhileable<TKey, T>
* @template-extends Duplicateable<TKey, T>
* @template-extends Everyable<TKey, T>
* @template-extends Explodeable<TKey, T>
* @template-extends Filterable<TKey, T>
* @template-extends Firstable<TKey, T>
Expand Down Expand Up @@ -214,6 +216,7 @@ interface Collection extends
Dropable,
DropWhileable,
Duplicateable,
Everyable,
Explodeable,
Falsyable,
Filterable,
Expand Down
20 changes: 20 additions & 0 deletions src/Contract/Operation/Everyable.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\Collection;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T of bool
*/
interface Everyable
{
/**
* @psalm-return \loophp\collection\Contract\Collection<TKey, bool>
*/
public function every(callable $callback): Collection;
}
59 changes: 59 additions & 0 deletions src/Operation/Every.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Generator;
use Iterator;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*
* phpcs:disable Generic.Files.LineLength.TooLong
*/
final class Every extends AbstractOperation
{
/**
* @psalm-return Closure((callable(T, TKey, Iterator<TKey, T>): bool)): Closure(Iterator<TKey, T>): Generator<TKey, bool>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-return Closure(Iterator<TKey, T>): Generator<TKey, bool>
*/
static function (callable $callback): Closure {
$callbackBuilder =
/**
* @psalm-param callable(T, TKey, Iterator<TKey, T>): bool $callback
*/
static function (callable $callback): Closure {
return
/**
* @param mixed $carry
* @psalm-param T $carry
*
* @param mixed $value
* @psalm-param T $value
*
* @param mixed $key
* @psalm-param TKey $key
* @psalm-param Iterator<TKey, T> $iterator
*/
static function ($carry, $value, $key, Iterator $iterator) use ($callback): bool {
return $callback($value, $key, $iterator);
};
};

/** @psalm-var Closure(Iterator<TKey, T>): Generator<TKey, bool> $foldLeft */
$foldLeft = FoldLeft::of()($callbackBuilder($callback))(true);

// Point free style.
return $foldLeft;
};
}
}

0 comments on commit 8ea76af

Please sign in to comment.