diff --git a/README.md b/README.md index 2927c73..6eff9f8 100644 --- a/README.md +++ b/README.md @@ -270,12 +270,21 @@ var_dump(\ArrayLookup\Finder::last( // RETURN the Array key, pass true to 3rd arg +// ... with PRESERVE original key var_dump(\ArrayLookup\Finder::last( $data, static fn ($datum): bool => $datum > 5, true )); // 3 +// ... with RESORT key, first key is last record +var_dump(\ArrayLookup\Finder::last( + $data, + static fn ($datum): bool => $datum > 5, + true, + false +)); // 0 + var_dump(\ArrayLookup\Finder::last( $data, static fn ($datum): bool => $datum < 5, diff --git a/src/Finder.php b/src/Finder.php index 25446fb..63838a3 100644 --- a/src/Finder.php +++ b/src/Finder.php @@ -56,8 +56,12 @@ 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, bool $returnKey = false): mixed - { + public static function last( + iterable $data, + callable $filter, + bool $returnKey = false, + bool $preserveKey = true + ): mixed { // convert to array when data is Traversable instance if ($data instanceof Traversable) { $data = self::resolveArrayFromTraversable($data); @@ -74,10 +78,15 @@ public static function last(iterable $data, callable $filter, bool $returnKey = end($data); // grab current key - $key = key($data); + $key = key($data); + $resortkey = -1; // key = null means no longer current data while ($key !== null) { + if (! $preserveKey && $returnKey) { + ++$resortkey; + } + $current = current($data); $isFound = $filter($current, $key); @@ -94,7 +103,15 @@ public static function last(iterable $data, callable $filter, bool $returnKey = continue; } - return $returnKey ? $key : $current; + if (! $returnKey) { + return $current; + } + + if ($preserveKey) { + return $key; + } + + return $resortkey; } return null; diff --git a/tests/FinderTest.php b/tests/FinderTest.php index eeaac0c..de1e73f 100644 --- a/tests/FinderTest.php +++ b/tests/FinderTest.php @@ -235,4 +235,31 @@ public function lastReturnKeyDataProvider(): array ], ]; } + + /** + * @dataProvider lastReturnKeyResortKeyDataProvider + */ + public function testLastReturnKeyResortKey(iterable $data, callable $filter, mixed $expected): void + { + $this->assertSame( + $expected, + Finder::last($data, $filter, true, false) + ); + } + + public function lastReturnKeyResortKeyDataProvider(): array + { + return [ + [ + [6, 7, 8, 9], + static fn($datum): bool => $datum > 5, + 0, + ], + [ + [6, 7, 8, 9], + static fn($datum): bool => $datum < 5, + null, + ], + ]; + } }