array_rand

(PHP 4, PHP 5, PHP 7, PHP 8)

array_randLiefert einen oder mehrere zufällige Schlüssel eines Arrays

Beschreibung

array_rand(array $array, int $num = 1): int|string|array

Wählt einen oder mehrere Einträge aus einem Array aus und gibt den Schlüssel des zufälligen Eintrags bzw. die Schlüssel der zufälligen Einträge zurück. Es wird ein Pseudo-Zufallszahlengenerator verwendet, der nicht für kryptographische Zwecke geeignet ist.

Parameter-Liste

array

Das Eingabe-Array.

num

Gibt an, wie viele Einträge ausgewählt werden sollen.

Rückgabewerte

Wenn nur ein Eintrag ausgewählt wird, gibt array_rand() den Schlüssel eines zufälligen Eintrages zurück. Andernfalls wird ein Array mit den Schlüsseln der zufälligen Einträge zurückgegeben. Dies hat den Zweck, dass zufällige Schlüssel und auch Werte aus dem Array ausgewählt werden können. Wenn mehrere Schlüssel zurückgegeben werden, werden sie in der Reihenfolge zurückgegeben, in der sie im ursprünglichen Array vorliegen. Der Versuch, mehr Elemente auszuwählen als im Array vorhanden sind, ergibt einen Fehler der Stufe E_WARNING und NULL wird zurückgegeben.

Changelog

Version Beschreibung
7.1.0 Zur Erzeugung der Zufallszahlen kommt intern nun der » Mersenne-Primzahlen-Zufallsgenerator statt der vorherigen libc-rand-Funktion zum Einsatz.

Beispiele

Beispiel #1 array_rand()-Beispiel

<?php
$input 
= array("Neo""Morpheus""Trinity""Cypher""Tank");
$rand_keys array_rand($input2);
echo 
$input[$rand_keys[0]] . "\n";
echo 
$input[$rand_keys[1]] . "\n";
?>

Siehe auch

  • shuffle() - Mischt die Elemente eines Arrays

add a note

User Contributed Notes 7 notes

up
68
Anonymous
12 years ago
If the array elements are unique, and are all integers or strings, here is a simple way to pick $n random *values* (not keys) from an array $array:

<?php array_rand(array_flip($array), $n); ?>
up
39
Anonymous
10 years ago
It doesn't explicitly say it in the documentation, but PHP won't pick the same key twice in one call.
up
3
divinity76+spam at gmail dot com
5 months ago
for a cryptographically secure version, try

<?php

/**
* fetch a random key from array, using a cryptograpically secure rng
* discussed+reviewed at https://codereview.stackexchange.com/questions/275832/cryptographically-secure-version-of-the-core-array-rand-function/
*
* @param array $array
* @throws ValueError if array is empty
* @return int|string key
*/
function array_rand_cryptographically_secure(array $array)/*: int|string*/ {
   
$max = count ( $array ) - 1;
    if (
$max < 0) {
        throw new
ValueError ( 'Argument #1 ($array) cannot be empty' );
    }
    return
key ( array_slice ( $array, random_int ( 0, $max ), 1, true ) );
}

$tests = [
        [
5, 6, 7],
        [
'a' => 1, 'b' => 2, 'c' => 3],
        [
'zero', 4 => 'four', 9 => 'nine'],
        [
"PEAN"=>0],
        []
];
foreach (
$tests as $test) {
    echo
array_rand_cryptographically_secure($test) . "\n";
}

?>
(this is an improved version, which unlike the first version, avoids copying *all* the keys)
up
17
grzeniufication
4 years ago
<?php

/**
* Wraps array_rand call with additional checks
*
* TLDR; not so radom as you'd wish.
*
* NOTICE: the closer you get to the input arrays length, for the n parameter, the  output gets less random.
* e.g.: array_random($a, count($a)) == $a will yield true
* This, most certainly, has to do with the method used for making the array random (see other comments).
*
* @throws OutOfBoundsException – if n less than one or exceeds size of input array
*
* @param array $array – array to randomize
* @param int $n – how many elements to return
* @return array
*/
function array_random(array $array, int $n = 1): array
{
    if (
$n < 1 || $n > count($array)) {
        throw new
OutOfBoundsException();
    }

    return (
$n !== 1)
        ?
array_values(array_intersect_key($array, array_flip(array_rand($array, $n))))
        : array(
$array[array_rand($array)]);
}
up
1
fulachan2 at gmail dot com
11 months ago
array_rand () takes a random value without ever being able to go back in its choice of random value.
A simple example:
I decide to mix an array of 10 entries to retrieve 3 values. This choice will give increasing and random values.

    $myarray = range(1,10);
   
    $pm = array_rand($myarray,3);     
    // $pm return array(0->0,1->6,2->8)

But if I decide to shuffle an array of 10 entries to get 10 entries, array_rand () will choose to assign a value to each return value and therefore the return array will not be random.

    $gm = array_rand($myarray,count($myarray));
    // $gm not random array(0->0,1->1,2->2,3->3,4->4,5->5,6->6,7->7,8->8,9->9)

The easiest way to have a truly random value:
either use array_rand () in a loop of 1 value at a time

$deg = range(-60,60);
$size = range(16,64);
$color = ["blue","red","green","pink","orange","purple","grey","darkgreen","darkkhaki"];
$i = 0;
$longueur = 10;
do{
    ++$i;
    printf("<span style='transform: rotateZ(%ddeg); display: inline-block;font-size: %spx; color:%s'>%s</span>",
        $deg[array_rand($deg)],
        $size[array_rand($size)],
        $color[array_rand($color)],
        $alnum[array_rand($alnum)]);

}while($i < $longueur);

------------------
or simply use shuffle () to shuffle the array really randomly.
up
11
grzeniufication
4 years ago
<?php
// An example how to fetch multiple values from array_rand
$a = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ];
$n = 3;

// If you want to fetch multiple values you can try this:
print_r( array_intersect_key( $a, array_flip( array_rand( $a, $n ) ) ) );

// If you want to re-index keys wrap the call in 'array_values':
print_r( array_values( array_intersect_key( $a, array_flip( array_rand( $a, $n ) ) ) ) );
up
-4
Vitaly
9 months ago
Generate random index in weights array.
Implementation of Vose's Alias Method.

<?php
class AliasMethod
{
    protected
$count;
    protected
$prob;
    protected
$alias;

    public function
__construct($weight)
    {
       
$count = count($weight);
       
$sum = array_sum($weight);
       
$d = $count / $sum;
       
$small = [];
       
$large = [];

        foreach (
$weight as $i => & $w) {
            if ( (
$w *= $d) < 1)
               
$small[] = $i;
            else
               
$large[] = $i;
        }
        unset(
$w);

       
$prob = [];
       
$alias = [];

        while (!empty(
$small) AND !empty($large)) {
           
$l = array_pop($small);
           
$g = array_pop($large);
           
$prob[$l] = $weight[$l];
           
$alias[$l] = $g;

            if ( (
$weight[$g] += $weight[$l] - 1) < 1)
               
$small[] = $g;
            else
               
$large[] = $g;
        }

        foreach (
$large as $i)
           
$prob[$i] = 1;

        foreach (
$small as $i)
           
$prob[$i] = 1;

       
$this->prob = $prob;
       
$this->alias = $alias;
       
$this->count = $count;

    }

    public function
next(): int
   
{
       
$i = mt_rand(0, $this->count - 1);
        if (
mt_rand() / mt_getrandmax() <= $this->prob[$i])
            return
$i;
        else
            return
$this->alias[$i];
    }
}

// Usage:

$weight = [1, 2, 1, 1, 100, 1, 1, 5, 1, 1];
$rnd = new AliasMethod($weight);

$results = array_fill(0, count($weight), 0);

for(
$i = 0; $i < 100000; ++$i) {
   
$results[$rnd->next()]++;
}
print_r($results);

/*
Array
(
    [0] => 901
    [1] => 1785
    [2] => 899
    [3] => 907
    [4] => 87655
    [5] => 867
    [6] => 836
    [7] => 4371
    [8] => 910
    [9] => 869
)
*/
To Top