From cb372612bccf49129ecc9b020affd27761ef6bfc Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Jan 2023 23:54:28 +0700 Subject: [PATCH 1/4] Add returnKey flag on Finder to allow return key instead of row --- src/Finder.php | 8 ++-- tests/FinderTest.php | 111 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 4 deletions(-) diff --git a/src/Finder.php b/src/Finder.php index 9745ef8..25446fb 100644 --- a/src/Finder.php +++ b/src/Finder.php @@ -21,7 +21,7 @@ final class Finder * @param array|Traversable $data * @param callable(mixed $datum, int|string|null $key=): bool $filter */ - public static function first(iterable $data, callable $filter): mixed + public static function first(iterable $data, callable $filter, bool $returnKey = false): mixed { foreach ($data as $key => $datum) { $isFound = $filter($datum, $key); @@ -33,7 +33,7 @@ public static function first(iterable $data, callable $filter): mixed continue; } - return $datum; + return $returnKey ? $key : $datum; } return null; @@ -56,7 +56,7 @@ private static function resolveArrayFromTraversable(Traversable $traversable): a * @param array|Traversable $data * @param callable(mixed $datum, int|string|null $key=): bool $filter */ - public static function last(iterable $data, callable $filter): mixed + public static function last(iterable $data, callable $filter, bool $returnKey = false): mixed { // convert to array when data is Traversable instance if ($data instanceof Traversable) { @@ -94,7 +94,7 @@ public static function last(iterable $data, callable $filter): mixed continue; } - return $current; + return $returnKey ? $key : $current; } return null; diff --git a/tests/FinderTest.php b/tests/FinderTest.php index 055c325..eeaac0c 100644 --- a/tests/FinderTest.php +++ b/tests/FinderTest.php @@ -51,6 +51,43 @@ public function firstDataProvider(): array ]; } + /** + * @dataProvider firstReturnKeyDataProvider + */ + public function testFirstReturnKey(iterable $data, callable $filter, mixed $expected): void + { + $this->assertSame( + $expected, + Finder::first($data, $filter, true) + ); + } + + public function firstReturnKeyDataProvider(): array + { + return [ + [ + [1, 2, 3], + static fn($datum): bool => $datum === 2, + 1, + ], + [ + [1, "1", 3], + static fn($datum): bool => $datum === 1000, + null, + ], + [ + ['abc test', 'def', 'some test'], + static fn(string $datum, int $key): bool => str_contains($datum, 'test') && $key >= 0, + 0, + ], + [ + ['abc test', 'def', 'some test'], + static fn(string $datum, int $key): bool => str_contains($datum, 'test') && $key === 1, + null, + ], + ]; + } + /** * @dataProvider lastDataProvider */ @@ -124,4 +161,78 @@ public function lastDataProvider(): array ], ]; } + + /** + * @dataProvider lastReturnKeyDataProvider + */ + public function testLastReturnKey(iterable $data, callable $filter, mixed $expected): void + { + $this->assertSame( + $expected, + Finder::last($data, $filter, true) + ); + } + + public function lastReturnKeyDataProvider(): array + { + $generator = static function (): Generator { + yield 6; + yield 7; + yield 8; + yield 9; + }; + + return [ + [ + [6, 7, 8, 9], + static fn($datum): bool => $datum > 5, + 3, + ], + [ + [6, 7, 8, 9], + static fn($datum): bool => $datum < 5, + null, + ], + [ + new ArrayIterator([6, 7, 8, 9]), + static fn($datum): bool => $datum > 5, + 3, + ], + [ + new ArrayIterator([6, 7, 8, 9]), + static fn($datum): bool => $datum < 5, + null, + ], + [ + new ArrayObject([6, 7, 8, 9]), + static fn($datum): bool => $datum > 5, + 3, + ], + [ + new ArrayObject([6, 7, 8, 9]), + static fn($datum): bool => $datum < 5, + null, + ], + [ + $generator(), + static fn($datum): bool => $datum > 5, + 3, + ], + [ + $generator(), + static fn($datum): bool => $datum < 5, + null, + ], + [ + ['abc test', 'def', 'some test'], + static fn(string $datum, int $key): bool => str_contains($datum, 'test') && $key >= 0, + 2, + ], + [ + ['abc test', 'def', 'some test'], + static fn(string $datum, int $key): bool => str_contains($datum, 'test') && $key === 1, + null, + ], + ]; + } } From eb3a51146fc898d5f91bf234b75736466cadb8bd Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Jan 2023 23:57:17 +0700 Subject: [PATCH 2/4] documentation --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 19e3bc9..6d5ee0e 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,15 @@ var_dump(\ArrayLookup\Finder::first($data, $filter)) // 1 $filter = static fn($datum): bool => $datum == 1000; var_dump(\ArrayLookup\Finder::first($data, $filter)) // null +// RETURN the Array key + +$filter = static fn($datum): bool => $datum === 1; + +var_dump(\ArrayLookup\Finder::first($data, $filter, true)) // 0 + +$filter = static fn($datum): bool => $datum == 1000; +var_dump(\ArrayLookup\Finder::first($data, $filter, true)) // null + // WITH key array included $filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0; @@ -259,6 +268,20 @@ var_dump(\ArrayLookup\Finder::last( static fn ($datum): bool => $datum < 5 )); // null +// RETURN the Array key + +var_dump(\ArrayLookup\Finder::last( + $data, + static fn ($datum): bool => $datum > 5, + true +)); // 3 + +var_dump(\ArrayLookup\Finder::last( + $data, + static fn ($datum): bool => $datum < 5, + 3 +)); // null + // WITH key array included var_dump(\ArrayLookup\Finder::last( From c4bea2237d3bf3eb2c9cdc6e4718d2768ef839cb Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Jan 2023 23:58:44 +0700 Subject: [PATCH 3/4] documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d5ee0e..1c9b963 100644 --- a/README.md +++ b/README.md @@ -279,7 +279,7 @@ var_dump(\ArrayLookup\Finder::last( var_dump(\ArrayLookup\Finder::last( $data, static fn ($datum): bool => $datum < 5, - 3 + true )); // null // WITH key array included From 8d18e27ce9064eb38676156874a43f5d0fceb437 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 13 Jan 2023 00:00:12 +0700 Subject: [PATCH 4/4] documentation --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1c9b963..2927c73 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ $filter = static fn($datum): bool => $datum === 4; var_dump(\ArrayLookup\AtLeast::once($data, $filter)) // false -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter $data = [1, 2, 3]; $filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0; @@ -77,7 +77,7 @@ $filter = static fn($datum): bool => $datum === 1; var_dump(\ArrayLookup\AtLeast::twice($data, $filter)) // false -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter $data = [1, "1", 3]; $filter = static fn($datum, $key): bool => $datum == 1 && $key >= 0; @@ -107,7 +107,7 @@ $times = 3; var_dump(\ArrayLookup\AtLeast::times($data, $filter, $times)) // false -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter $data = [false, null, 0]; $filter = static fn($datum, $key): bool => ! $datum && $key >= 0; @@ -141,7 +141,7 @@ $filter = static fn($datum): bool => $datum == 1; var_dump(\ArrayLookup\Only::once($data, $filter)) // false -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter $data = [1, 2, 3]; $filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0; @@ -170,7 +170,7 @@ $filter = static fn($datum): bool => (bool) $datum; var_dump(\ArrayLookup\Only::twice($data, $filter)) // false -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter $data = [1, "1", 3]; $filter = static fn($datum, $key): bool => $datum == 1 && $key >= 0; @@ -201,7 +201,7 @@ $times = 2; var_dump(\ArrayLookup\Only::times($data, $filter, $times)) // false -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter $data = [false, null, 1]; $filter = static fn($datum, $key): bool => ! $datum && $key >= 0; @@ -233,7 +233,7 @@ var_dump(\ArrayLookup\Finder::first($data, $filter)) // 1 $filter = static fn($datum): bool => $datum == 1000; var_dump(\ArrayLookup\Finder::first($data, $filter)) // null -// RETURN the Array key +// RETURN the Array key, pass true to 3rd arg $filter = static fn($datum): bool => $datum === 1; @@ -242,7 +242,7 @@ var_dump(\ArrayLookup\Finder::first($data, $filter, true)) // 0 $filter = static fn($datum): bool => $datum == 1000; var_dump(\ArrayLookup\Finder::first($data, $filter, true)) // null -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter $filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0; @@ -268,7 +268,7 @@ var_dump(\ArrayLookup\Finder::last( static fn ($datum): bool => $datum < 5 )); // null -// RETURN the Array key +// RETURN the Array key, pass true to 3rd arg var_dump(\ArrayLookup\Finder::last( $data, @@ -282,7 +282,7 @@ var_dump(\ArrayLookup\Finder::last( true )); // null -// WITH key array included +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter var_dump(\ArrayLookup\Finder::last( $data,