diff --git a/README.md b/README.md index 19e3bc9..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,16 @@ var_dump(\ArrayLookup\Finder::first($data, $filter)) // 1 $filter = static fn($datum): bool => $datum == 1000; var_dump(\ArrayLookup\Finder::first($data, $filter)) // null -// WITH key array included +// RETURN the Array key, pass true to 3rd arg + +$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, pass $key variable as 2nd arg on filter to be used in filter $filter = static fn($datum, $key): bool => $datum === 1 && $key >= 0; @@ -259,7 +268,21 @@ var_dump(\ArrayLookup\Finder::last( static fn ($datum): bool => $datum < 5 )); // null -// WITH key array included +// RETURN the Array key, pass true to 3rd arg + +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, + true +)); // null + +// WITH key array included, pass $key variable as 2nd arg on filter to be used in filter var_dump(\ArrayLookup\Finder::last( $data, 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, + ], + ]; + } }