From ae9ada9dbb90362596f41bc1300b319245b44fe3 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Wed, 27 Mar 2024 13:32:25 +0100 Subject: [PATCH] feat: add support for filtering using key --- src/IterableObject.php | 8 ++++++-- src/iterable-functions.php | 2 +- tests/IterableFilterTest.php | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/IterableObject.php b/src/IterableObject.php index 6a987ff..c36f7f6 100644 --- a/src/IterableObject.php +++ b/src/IterableObject.php @@ -16,6 +16,8 @@ use function array_map; use function iterator_to_array; +use const ARRAY_FILTER_USE_BOTH; + /** * @internal * @@ -40,7 +42,7 @@ public function __construct(iterable $iterable, bool $preserveKeys = true) } /** - * @param (callable(TValue):bool)|null $filter + * @param (callable(TValue):bool)|(callable(TValue,TKey):bool)|null $filter * * @return self */ @@ -56,7 +58,9 @@ static function ($value): bool { return new self(new CallbackFilterIterator(new IteratorIterator($this->iterable), $filter)); } - $filtered = $filter === null ? array_filter($this->iterable) : array_filter($this->iterable, $filter); + $filtered = $filter === null + ? array_filter($this->iterable) + : array_filter($this->iterable, $filter, ARRAY_FILTER_USE_BOTH); return new self($filtered); } diff --git a/src/iterable-functions.php b/src/iterable-functions.php index 1253042..239eb3e 100644 --- a/src/iterable-functions.php +++ b/src/iterable-functions.php @@ -87,7 +87,7 @@ function iterable_to_traversable(iterable $iterable): Traversable /** * Filters an iterable. * - * @param (callable(TValue):bool)|null $filter + * @param (callable(TValue):bool)|(callable(TValue,TKey):bool)|null $filter * * @psalm-param iterable $iterable * @psalm-return iterable diff --git a/tests/IterableFilterTest.php b/tests/IterableFilterTest.php index ea0b4ca..e7b1d6a 100644 --- a/tests/IterableFilterTest.php +++ b/tests/IterableFilterTest.php @@ -4,6 +4,7 @@ namespace BenTools\IterableFunctions\Tests; +use Generator; use SplFixedArray; use Traversable; @@ -47,3 +48,28 @@ static function ($input): bool { assert($filtered instanceof Traversable); assertSame([1 => 'bar'], iterator_to_array($filtered)); }); + +it('filters a Traversable object with a callback using key', function (): void { + $iterable = (function (): Generator { + yield 'foo' => 1; + yield 'bar' => 1; + })(); + $filter = + static function (int $input, string $key): bool { + return $key === 'bar'; + }; + $filtered = iterable_filter($iterable, $filter); + assert($filtered instanceof Traversable); + assertSame(['bar' => 1], iterator_to_array($filtered)); +}); + +it('filters an array with a callback using key', function (): void { + $iterable = ['foo' => 1, 'bar' => 1]; + $filter = + static function (int $input, string $key): bool { + return $key === 'bar'; + }; + $filtered = iterable_filter($iterable, $filter); + assert($filtered instanceof Traversable); + assertSame(['bar' => 1], iterator_to_array($filtered)); +});