diff --git a/spec/loophp/collection/CollectionSpec.php b/spec/loophp/collection/CollectionSpec.php index 09f2f5f2f..73d8305be 100644 --- a/spec/loophp/collection/CollectionSpec.php +++ b/spec/loophp/collection/CollectionSpec.php @@ -717,12 +717,12 @@ public function it_can_dropWhile(): void return 3 > $value; }; - $isGreaterThanFive = static function (int $value): bool { + $isSmallerThanFive = static function (int $value): bool { return 5 > $value; }; $this::fromIterable([1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]) - ->dropWhile($isGreaterThanFive, $isSmallerThanThree) + ->dropWhile($isSmallerThanFive, $isSmallerThanThree) ->shouldIterateAs([ 2 => 3, 3 => 4, diff --git a/src/Operation/DropWhile.php b/src/Operation/DropWhile.php index 5e4fea607..7136f6bba 100644 --- a/src/Operation/DropWhile.php +++ b/src/Operation/DropWhile.php @@ -14,41 +14,69 @@ * @psalm-template T * * phpcs:disable Generic.Files.LineLength.TooLong + * phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact */ final class DropWhile extends AbstractOperation { /** - * @psalm-return Closure(callable(T , TKey , Iterator ): bool):Closure (Iterator): Generator + * @psalm-return Closure(callable(T , TKey ): bool ...):Closure (Iterator): Generator */ public function __invoke(): Closure { return /** - * @psalm-param callable(T, TKey, Iterator):bool $callback + * @psalm-param callable(T, TKey):bool ...$callbacks * * @psalm-return Closure(Iterator): Generator */ - static fn (callable ...$callbacks): Closure => static function (Iterator $iterator) use ($callbacks): Generator { - $break = false; + static fn (callable ...$callbacks): Closure => + /** + * @psalm-param Iterator $iterator + * + * @psalm-return Generator + */ + static function (Iterator $iterator) use ($callbacks): Generator { + $reducerCallback = + /** + * @param mixed $key + * @psalm-param TKey $key + * + * @psalm-return Closure(T): Closure(Iterator): Closure(bool, callable(T, TKey, Iterator): bool): bool + */ + static fn ($key): Closure => + /** + * @param mixed $current + * @psalm-param T $current + * + * @psalm-return Closure(Iterator): Closure(bool, callable(T, TKey, Iterator): bool): bool + */ + static fn ($current): Closure => + /** + * @psalm-param Iterator $iterator + * + * @psalm-return Closure(bool, callable(T, TKey, Iterator): bool): bool + */ + static fn (Iterator $iterator): Closure => + /** + * @psalm-param bool $carry + * @psalm-param callable(T, TKey, Iterator): bool $callable + */ + static fn (bool $carry, callable $callable): bool => ($callable($current, $key, $iterator)) ? $carry : false; foreach ($iterator as $key => $current) { - if (false === $break) { - $reduced = array_reduce( - $callbacks, - static fn (bool $carry, callable $callback): bool => ($callback($current, $key, $iterator)) ? - $carry : - false, - true - ); + $result = array_reduce( + $callbacks, + $reducerCallback($key)($current)($iterator), + true + ); - if (true === $reduced) { - continue; - } - - $break = true; + if (false === $result) { + break; } + } - yield $key => $current; + for (; $iterator->valid(); $iterator->next()) { + yield $iterator->key() => $iterator->current(); } }; }