Skip to content

Commit 7d2f48a

Browse files
committed
added Arrays::firstKey(), lastKey()
1 parent 07d6808 commit 7d2f48a

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

src/Utils/Arrays.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,9 @@ public static function last(array $array, ?callable $predicate = null): mixed
154154

155155
/**
156156
* Returns the key of first matching item the specified predicate or null if there is no such item.
157+
* The callback has the signature `function ($value, $key, $array): bool`.
157158
*/
158-
private static function firstKey(array $array, callable $predicate): int|string|null
159+
public static function firstKey(array $array, callable $predicate): int|string|null
159160
{
160161
foreach ($array as $k => $v) {
161162
if ($predicate($v, $k, $array)) {
@@ -166,6 +167,16 @@ private static function firstKey(array $array, callable $predicate): int|string|
166167
}
167168

168169

170+
/**
171+
* Returns the key of last matching item the specified predicate or null if there is no such item.
172+
* The callback has the signature `function ($value, $key, $array): bool`.
173+
*/
174+
public static function lastKey(array $array, callable $predicate): int|string|null
175+
{
176+
return self::firstKey(array_reverse($array, preserve_keys: true), $predicate);
177+
}
178+
179+
169180
/**
170181
* Inserts the contents of the $inserted array into the $array immediately after the $key.
171182
* If $key is null (or does not exist), it is inserted at the beginning.

tests/Utils/Arrays.firstKey().phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nette\Utils\Arrays;
6+
use Tester\Assert;
7+
8+
require __DIR__ . '/../bootstrap.php';
9+
10+
11+
test('internal array pointer is not affected', function () {
12+
$arr = [1, 2, 3];
13+
end($arr);
14+
Assert::null(Arrays::firstKey($arr, fn() => false));
15+
Assert::same(3, current($arr));
16+
});
17+
18+
test('with predicate', function () {
19+
Assert::null(Arrays::firstKey([], fn() => true));
20+
Assert::null(Arrays::firstKey([], fn() => false));
21+
Assert::null(Arrays::firstKey(['' => 'x'], fn() => false));
22+
Assert::same(0, Arrays::firstKey([null], fn() => true));
23+
Assert::null(Arrays::firstKey([null], fn() => false));
24+
Assert::same(0, Arrays::firstKey([1, 2, 3], fn() => true));
25+
Assert::null(Arrays::firstKey([1, 2, 3], fn() => false));
26+
Assert::same(2, Arrays::firstKey([1, 2, 3], fn($v) => $v > 2));
27+
Assert::same(0, Arrays::firstKey([1, 2, 3], fn($v) => $v < 2));
28+
});
29+
30+
test('predicate arguments', function () {
31+
Arrays::firstKey([2 => 'x'], fn() => Assert::same(['x', 2, [2 => 'x']], func_get_args()));
32+
});

tests/Utils/Arrays.lastKey().phpt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nette\Utils\Arrays;
6+
use Tester\Assert;
7+
8+
require __DIR__ . '/../bootstrap.php';
9+
10+
11+
test('internal array pointer is not affected', function () {
12+
$arr = [1, 2, 3];
13+
Assert::same(2, Arrays::lastKey($arr, fn() => true));
14+
Assert::same(1, current($arr));
15+
});
16+
17+
test('with predicate', function () {
18+
Assert::null(Arrays::lastKey([], fn() => true));
19+
Assert::null(Arrays::lastKey([], fn() => false));
20+
Assert::null(Arrays::lastKey(['' => 'x'], fn() => false));
21+
Assert::same(0, Arrays::lastKey([null], fn() => true));
22+
Assert::null(Arrays::lastKey([null], fn() => false));
23+
Assert::same(2, Arrays::lastKey([1, 2, 3], fn() => true));
24+
Assert::null(Arrays::lastKey([1, 2, 3], fn() => false));
25+
Assert::same(2, Arrays::lastKey([1, 2, 3], fn($v) => $v > 2));
26+
Assert::same(0, Arrays::lastKey([1, 2, 3], fn($v) => $v < 2));
27+
});
28+
29+
test('predicate arguments', function () {
30+
Arrays::lastKey([2 => 'x'], fn() => Assert::same(['x', 2, [2 => 'x']], func_get_args()));
31+
});

0 commit comments

Comments
 (0)