Skip to content

Commit

Permalink
refactor: Update MatchOne operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Jan 8, 2021
1 parent c8c3d9b commit d1bdbdf
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ The returned value of the operation is ``true`` when the callback match at least
of the collection. ``false`` otherwise.

If you want to match the ``user callback`` against another value (other than ``true``), you must
provide your own ``matcher callback`` as a second argument.
provide your own ``matcher callback`` as a second argument, it must returns a ``boolean``.

Interface: `Matchable`_

Expand Down
4 changes: 2 additions & 2 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -1624,8 +1624,8 @@ static function (int $value): bool {

$this::fromIterable($input)
->match(
static fn (int $value): string => 5 === $value ? 'foo' : 'bar',
static fn (): string => 'foo'
static fn (int $value): bool => 5 !== $value,
static fn (): bool => false
)
->shouldIterateAs([4 => true]);
}
Expand Down
38 changes: 34 additions & 4 deletions src/Operation/MatchOne.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,54 @@
final class MatchOne extends AbstractOperation
{
/**
* @psalm-return Closure(callable(T, TKey, Iterator<TKey, T>): T): Closure(callable(T, TKey, Iterator<TKey, T>): T): Closure(Iterator<TKey, T>): Generator<int, bool>
* @psalm-return Closure(callable(T, TKey, Iterator<TKey, T>): T): Closure(callable(T, TKey, Iterator<TKey, T>): bool): Closure(Iterator<TKey, T>): Generator<int, bool>
*/
public function __invoke(): Closure
{
return
/**
* @psalm-param callable(T, TKey, Iterator<TKey, T>): T $matcher
*
* @psalm-return Closure(callable(T, TKey, Iterator<TKey, T>): T): Closure(Iterator<TKey, T>): Generator<int, bool>
* @psalm-return Closure(callable(T, TKey, Iterator<TKey, T>): bool): Closure(Iterator<TKey, T>): Generator<int, bool>
*/
static function (callable $matcher): Closure {
return
/**
* @psalm-param callable(T, TKey, Iterator<TKey, T>): T $callback
* @psalm-param callable(T, TKey, Iterator<TKey, T>): bool ...$callbacks
*
* @psalm-return Closure(Iterator<TKey, T>): Generator<int, bool>
*/
static function (callable $callback) use ($matcher): Closure {
static function (callable ...$callbacks) use ($matcher): Closure {
$callbackReducer =
/**
* @psalm-param list<callable(T, TKey, Iterator<TKey, T>): bool> $callbacks
*
* @psalm-return Closure(T, TKey, Iterator<TKey, T>): bool
*/
static function (array $callbacks): Closure {
return
/**
* @psalm-param T $value
*
* @param mixed $value
*
* @psalm-param TKey $key
*
* @param mixed $key
*
* @psalm-param Iterator<TKey, T> $iterator
*/
static function ($value, $key, Iterator $iterator) use ($callbacks): bool {
return array_reduce(
$callbacks,
static fn (bool $carry, callable $callback): bool => ($carry || $callback($value, $key, $iterator)),
false
);
};
};

$callback = $callbackReducer($callbacks);

$mapCallback =
/**
* @param mixed $value
Expand Down

0 comments on commit d1bdbdf

Please sign in to comment.