Skip to content

Commit c5aba0b

Browse files
committed
:octocat: added Arr::random()
1 parent 72c639a commit c5aba0b

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

src/Arr.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
use function array_key_first;
1515
use function array_key_last;
16+
use function array_keys;
17+
use function count;
18+
use function random_int;
19+
use const PHP_VERSION_ID;
1620

1721
/**
1822
* Array functions
@@ -51,4 +55,32 @@ public static function last(array $array):mixed{
5155
return $array[array_key_last($array)];
5256
}
5357

58+
/**
59+
* Returns a random element of the given array, `null` if the given array is empty.
60+
*
61+
* @see \random_int() - PHP <= 8.1
62+
* @see \Random\Randomizer::pickArrayKeys() - PHP >= 8.2
63+
*
64+
* @param array<string|int, mixed> $array
65+
*
66+
* @noinspection PhpFullyQualifiedNameUsageInspection
67+
*/
68+
public static function random(array $array):mixed{
69+
70+
if($array === []){
71+
return null;
72+
}
73+
74+
if(PHP_VERSION_ID >= 80200){
75+
$key = (new \Random\Randomizer(new \Random\Engine\Secure))->pickArrayKeys($array, 1)[0];
76+
}
77+
else{
78+
// array_rand() is not cryptographically secure
79+
$keys = array_keys($array);
80+
$key = $keys[random_int(0, (count($keys) - 1))];
81+
}
82+
83+
return $array[$key];
84+
}
85+
5486
}

tests/ArrTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
/**
3+
* ArrTest.php
4+
*
5+
* @created 25.06.2025
6+
* @author smiley <[email protected]>
7+
* @copyright 2025 smiley
8+
* @license MIT
9+
*/
10+
declare(strict_types = 1);
11+
12+
namespace chillerlan\UtilitiesTest;
13+
14+
use chillerlan\Utilities\Arr;
15+
use PHPUnit\Framework\Attributes\CoversClass;
16+
use PHPUnit\Framework\Attributes\Test;
17+
use PHPUnit\Framework\TestCase;
18+
19+
#[CoversClass(Arr::class)]
20+
final class ArrTest extends TestCase{
21+
22+
private const testArray = [
23+
'one' => 1,
24+
'two' => 2,
25+
'three' => 3,
26+
'four' => 4,
27+
'five' => 5,
28+
];
29+
30+
#[Test]
31+
public function first():void{
32+
$first = Arr::first(self::testArray);
33+
34+
$this::assertSame(1, $first);
35+
}
36+
37+
#[Test]
38+
public function last():void{
39+
$last = Arr::last(self::testArray);
40+
41+
$this::assertSame(5, $last);
42+
}
43+
44+
#[Test]
45+
public function random():void{
46+
$random = Arr::random(self::testArray);
47+
48+
$this::assertContains($random, self::testArray);
49+
}
50+
51+
}

0 commit comments

Comments
 (0)