PHP 5.6.0 released

array_rand

(PHP 4, PHP 5)

array_rand Estrae a caso uno o più elementi da un array

Descrizione

mixed array_rand ( array $input [, int $num_req ] )

array_rand() è piuttosto utile quando si vuole estrarre a caso uno o più elementi da un array. Prende un array (input) e un argomento ozpionale (num_req) che specifica quanti elementi estrarre - se non è specificato, è 1 per default.

Se si sta estraendo solo un elemento, array_rand() restituisce la chiave di un elemento. Altrimenti, restituisce un array di chiavi. Questo viene fatto in modo da permettere di estrarre dall'array sia le chiavi che i valori.

Nota: Dal PHP 4.2.0, non c'è più bisogno di inizializzare il generatore di nomeri casuali con srand() o mt_srand() dal momento che questo viene fatto automaricamente.

Example #1 esempio di array_rand()

<?
srand
((float) microtime() * 10000000);
$input = array("Neo""Morpheus""Trinity""Cypher""Tank");
$chiavi array_rand($input2);
echo 
$input[$chiavi[0]] . "\n";
echo 
$input[$chiavi[1]] . "\n";
?>

Vedere anche shuffle().

add a note add a note

User Contributed Notes 26 notes

up
27
Sebmil
3 years ago
Looks like this function has a strange randomness.

If you take any number of elements in an array which has 40..100 elements, the 31st one is always by far the less occuring (by about 10% less than others).

I tried this piece of code at home (PHP Version 5.3.2-1ubuntu4.9) and on my server (PHP Version 5.2.17), unfortunately i haven't any server with the last version here :

<?php
$valeurs
= range(1, 40);
$proba = array_fill(1, 40, 0);
for (
$i = 0; $i < 10000; ++$i)
{
   
$tirage_tab = array_rand($valeurs, 10);
    foreach(
$tirage_tab as $key => $value)
    {
       
$proba[$valeurs[$value]]++;
    }
}

asort($proba);
echo
"Proba : <br/>\n";
foreach(
$proba as $key => $value)
{
    echo
"$key : $value<br/>\n";
}
?>

In every try, the number of occurrences change a bit but the 31 is always far less (around 2200) than the others (2400-2600). I tried with 50 and 100 elements, no change. I tried with more or less elements to pick (second parameter to array_rand), same result. If you pick only one element it's even worse : 31 has half the result of the others.

For this particular case, i recommend shuffling the array and taking the nth first elements, in this test it's 60% faster and the statistics are ok.
up
9
qeremy
2 years ago
An example for getting random value from arrays;

<?php
function array_random($arr, $num = 1) {
   
shuffle($arr);
   
   
$r = array();
    for (
$i = 0; $i < $num; $i++) {
       
$r[] = $arr[$i];
    }
    return
$num == 1 ? $r[0] : $r;
}

$a = array("apple", "banana", "cherry");
print_r(array_random($a));
print_r(array_random($a, 2));
?>

cherry
Array
(
    [0] => banana
    [1] => apple
)

And example for getting random value from assoc arrays;

<?php
function array_random_assoc($arr, $num = 1) {
   
$keys = array_keys($arr);
   
shuffle($keys);
   
   
$r = array();
    for (
$i = 0; $i < $num; $i++) {
       
$r[$keys[$i]] = $arr[$keys[$i]];
    }
    return
$r;
}

$a = array("a" => "apple", "b" => "banana", "c" => "cherry");
print_r(array_random_assoc($a));
print_r(array_random_assoc($a, 2));
?>

Array
(
    [c] => cherry
)
Array
(
    [a] => apple
    [b] => banana
)
up
5
Jordan Doyle
1 year ago
Note: array_rand uses the libc generator, which is slower and less-random than Mersenne Twister.

<?php
    $a
= ['http://php.net/', 'http://google.com/', 'http://bbc.co.uk/'];

   
$website = $a[mt_rand(0, count($a) - 1)];
?>

This is a better alternative.
up
2
Will-ster
8 years ago
This is something I have been playing with for quite awhile. I'm very new to php, but i finally got it to work. it's a function that will take and array[$arrquo] and find a particular keyword[$find] in the different elements of the array then take those elements that posess that keyword and display them at random

<?php
function popbyword($arrquo,$find)
{
$newarr = array('');
foreach(
$arrquo as $line)
{
  if(
strstr( $line, $find ) )
  {
   
array_push($newarr, $line);

  }
}   
srand((double)microtime()*1000000);
$rquote = array_rand($newarr);
echo
$newarr[$rquote];
}

popbyword($images, 'Albert');
?>

In my case I had this huge array of quotes with 90 some elements. I was able to find certain keywords in those elements then ONLY display the elements that had those keywords. NEAT! Maybe only because I'm new.
up
5
herodesh [-at_] gmail [-dot-] com
6 years ago
this is to generate a random selection from an array with array_rand preety nice, can be used to generate random passwords or anything:

$my_array = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "0", "1", "2", "3", "4", "5");
        for ($i=0; $i<=10; $i++)
        {
            $random = array_rand($my_array);
                        //this generates the random number from the array
            $parola .= $my_array[$random];
                        //here we will display the exact charachter from the array
        }
        echo $parola; // printing result
up
2
asarnoNOSPAM@interbaun DOT com
11 years ago
It is correct that using array_rand() with num_req=1 will return an integer and not an array, but why get so complicated with getting just the one value.  The K.I.S.S. method would suggest to do it this way:

<?
srand((double)microtime() * 10000000);
$originalArray = array("red", "blue", "green", "brown",
"cyan", "magenta", "purle", "cheezy");
$pickOne = array_rand($originalArray, 1);
$aRandomSelection = $originalArray[$pickOne ];
echo "$aRandomSelection was the random selection made";
?>

You only need to use the foreach if the num_req >=2. In those cases the array_rand() function will return an array of random elements which are a subset of the original array.  When num_req = 1, the array_rand() function returns an integer that signifies a randomly picked key of the original array.  Hope this clarifies things ... it works for me.
up
3
Anonymous
4 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
2
nospamplease at mail dot com
1 year ago
Random choice with a closure.

$randomChoice  = function($array) {return $array[array_rand($array)];};

$names = ['Dexter', 'Esther', 'David', 'Richard', 'Rachel', 'Belinda'];

echo $randomChoice($names);
up
3
uvm at sun dot he dot net
13 years ago
If you're just trying to draw a random subset of n elements from an array, it seems more effecient to do something like this:

<?php
function draw_rand_array($array,$draws)
{
       
$lastIndex = count($array) - 1;
       
$returnArr = array();
        while(
$draws > 1)
        {
               
$rndIndex = rand(0,$lastIndex);
               
array_push($returnArr,array_splice($array,$rndIndex,1));
               
$draws--;
               
$lastIndex--;
        }

        return
$returnArr;
}
?>

No messing with indexes when you're done... you just have an array with the elements you're looking for in it.
up
1
mickoz[at]parodius[dot]com
11 years ago
For those of you thinking that it does not work for num_req = 1, it is because it return a variable and not an array.  This mainly cause some problem with people using foreach.

The correct way to handle this is explained by that example:

<?php
$some_array
= array("blah","bleh","foo","lele");

$nb_value = 1;

srand ((float) microtime() * 10000000);
$rand_keys = array_rand($some_array, $nb_value);

if(!
is_array($rand_keys))
{
 
$rand_keys = array($rand_keys);
}

print_r($rand_keys); // verify here the array of keys
echo "\n<BR>";
?>

// You can then correctly use the foreach, as it require an array to work
// If you use foreach with one element, it won't work.

<?php
$random_array
= array();

foreach(
$rand_keys as $value)
{
 
array_push($random_array, $some_array[$value]);
}

print_r($random_array);
?>
up
1
josh at 3io dot com
12 years ago
I modified fake_array_rand to always only return 1 element, and did some benchmarks against calling array_rand with the second parameter as 1.  I ran 100 samples for each function for each number of elements and took the average result.  While the internal array_rand is faster for a small number of elements, it scales very poorly.

1 elements: 2.0619630813599E-05 sec. for array_rand,8.4352493286133E-05 sec. for fake_array_rand
10 elements: 2.1675825119019E-05 sec. for array_rand,8.427619934082E-05 sec. for fake_array_rand
100 elements: 2.9319524765015E-05 sec. for array_rand,8.4599256515503E-05 sec. for fake_array_rand
1000 elements: 0.0001157283782959 sec. for array_rand,8.5572004318237E-05 sec. for fake_array_rand
10000 elements: 0.0016669762134552 sec. for array_rand,8.5201263427734E-05 sec. for fake_array_rand
100000 elements: 0.015599734783173 sec. for array_rand,8.5580348968506E-05 sec. for fake_array_rand
1000000 elements: 0.18011983394623 sec. for array_rand,8.6690187454224E-05 sec. for fake_array_rand

<?php
function fake_array_rand ($array)
{
       
$count = count ($array);
       
# Help keep the number generator random :)
       
$randval and usleep ("0.$randval");

       
# Seed the random number generator
        # Generate a random number
       
srand ((double) microtime() * 10000000);
       
$randval = rand();

       
# Use the random value to 'pick' an entry from the array
        # Count the number of times that the entry is picked
       
++$index[$randval % $count];

        return
$array[$randval % $count];
}
?>
up
2
dragonfly at dragonflyeye dot net
8 years ago
Well, this is interesting.   I don't see anyone else commenting on this, so just in case you were planning to use this function like I was, be prepared: array_rand does not handle multidimensional arrays.  It just ends up returning a list of the X-axis values without the Y-axis arrays.  Bummer.  I'm going to have to find another way to do what I wanted.
up
2
jpinedo
10 years ago
An array of arrays example:

<?php
$banners
[0]['imagen']="imagen0.gif";
$banners[0]['url']="www.nosenada.tal";

$banners[1]['imagen']="imagen1.gif";
$banners[1]['url']="www.nose.tal";

$banners[2]['imagen']="imagen2.gif";
$banners[2]['url']="pagina.html";

$banners[3]['imagen']="imagen3.jpg";
$banners[3]['url']="../pagina.php";

$id_banner = array_rand($banners);

echo 
"Archivo:--".$banners[$id_banner]['imagen']. "<br />\n";
echo 
"URL:-----".$banners[$id_banner]['url']. "<br />\n";
?>
up
1
admin at jeremyzaretski dot com
5 years ago
<?php
// a foreach friendly version of array_rand
function Select_Random_Indices($source_array, $count = 1)
{
    if(
$count > 0)
    {
        if(
$count == 1)
        {
           
$result = array(array_rand($source_array, $count));
        }
        else
        {
           
$result = array_rand($source_array, $count);
        }
    }
    else
    {
       
$result = array();
    }

    return
$result;
}

// using the above function to pick random values instead of entries
function Select_Random_Entries($source_array, $count = 1)
{
   
$result = array();
   
$index_array = Select_Random_Indices($source_array, $count);

    foreach(
$index_array as $index)
    {
       
$result[$index] = $source_array[$index];
    }

    return
$result;
}
?>
up
1
maxnamara at yahoo dot com
9 years ago
<?php
$input
= array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");

function
my_array_rand($input,$i=2){
srand((float) microtime() * 10000000);

$rand_keys = array_rand($input, $i);

/*
print $input[$rand_keys[0]] . "\n";
print $input[$rand_keys[1]] . "\n";
*/

$res = array();

if(
$i > 1){

for(
$a=0;$a<$i;$a++){

   
$res[] = $input[$rand_keys[$a]];
   
}

}
else{

   
$res[] = $input[$rand_keys];   
   
}

return
$res;
}

$a = my_array_rand($input,3);
echo
"<pre>";
print_r($a);
echo
"</pre>";
?>
up
1
Paul Hodel (paul at ue dot com dot br)
11 years ago
If you trying to get a randon array just use that... it's easier! And you have no repeats...

<?

srand ((float) microtime() * 10000000);

$input = array ("Neo", "Morpheus", "Trinity", "Cypher", "Tank");

$keys = array_rand ($input, sizeof($input));

while (list($k, $v) = each($keys))
{
    echo $new_input = $input[$v];
}

?>
up
1
info at pavliga dot com
5 years ago
If you want get unique range:

<?php
$n
= 15;

$data = range(1, 20);
$rand = array_rand($data,$n);

for(
$i=0; $i<$n; $i++)
{
echo
$rand[$i]."<br>";
}

?>
up
1
Frederick Lemasson aka djassper at gmail
7 years ago
To select a random Value (not a Key) from a Multi-Dimentionnal array I made a recursive function : array_multi_rand()

the following exemple randomly selects an url from a multidimentionnal array :

<?

$Expos['Google']['Science']='news.google.fr/news?topic=t';
$Expos['Google']['Economie']='news.google.fr/news?topic=b';
$Expos['Google']['Sante']='news.google.fr/news?topic=m';
$Expos['Yahoo']='fr.news.yahoo.com';
$Expos['Events']['LogicielLibre']='agendadulibre.org';
$Expos['MyBlog']='www.kik-it.com';

function array_multi_rand($Zoo){
    $Boo=array_rand($Zoo);
    if(is_array($Zoo[$Boo])){
        return array_multi_rand($Zoo[$Boo]);
    }else{
        return $Zoo[$Boo];
    }
}

echo(array_multi_rand($Expos));

?>
up
1
alexkropivko at(dog) yandex dot ru
9 years ago
There was a mistake at "Paul Hodel (paul at ue dot com dot br) 17-Apr-2003 04:40":
String
echo $new_input = $input[$v];

have to be:
echo $new_input[] = $input[$v];
up
1
scandar at home dot se
11 years ago
Note that the int num_req parameter is the required number of element to randomly select. So if your array has 3 element and num_req=4 then array_rand() will not return anything since it is impossible to select 4 random elements out of an array that only contains 3 elements. Many people think that they will get 3 elements returned but that is of course not the case.
up
1
john at brahy dot com
3 months ago
if you want random elements from an array, this worked pretty well for me.

<?php
//using shuffle randomizes the order of elements

function get_random_elements( $array,$limit = 0 ) {
   
   
shuffle($array);

    if (
$limit > 0 ) {
       
$array = array_splice($array, 0, $limit);
    }
    return
$array;
}
?>
up
0
JS
7 years ago
I wanted to write something that picks a random entry from a 1column-MySQL database - simply Post Of The Moment (potm). I know there surly are many better ways to do it, but I`m rather new to PHP :)  Anyway, it`s simple and no-problem working code.
Of course I assume your DB exists and you always have something in it.

@$link = MySQL_Connect("localhost", "username", "password"); //connect to mysql
mySQL_Select_DB("database"); //..to DB
@$potms = MySQL_Query("SELECT * FROM potm"); //now we get all from our table and store it
MySQL_Close($link); //there`s no need for connection, so we should close it

$potm_array = ''; //sets variables to "zero" values
$i = 0;
while ($entry = MySQL_Fetch_Array($potms)) //now we go through our DB
       {
         $potm_array[$i] = $entry; //our temporary array from which we will random pick a field key
         $i++; //now we increment our field key
       }

$potm_id = array_rand($potw_array); //picks a random key from array
$potm = $potm_array[$potm_id]['name_of_the_field']; //now we have stored our Post Of The Moment in $potm

..hope this helps
up
0
trukin at gmail dot com
8 years ago
Modify of last note:
<?php
if (!function_exists('array_rand')) {
    function
array_rand($array, $lim=1) {
       
mt_srand((double) microtime() * 1000000);
        for(
$a=0; $a<=$lim; $a++){
           
$num[] = mt_srand(0, count($array)-1);
        }
        return @
$num;
    }
}
?>

mt_rand generates a better random number, and with the limit.
up
0
bjcffnet at gmail dot com
9 years ago
As wazaawazaa600 at msn dot com pointed out, a multi-dimensional array doesn't work with this function. So, I hope I can help someone with this :)

<?php
/**
* Returns a number of random elements from an array.
*
* It returns the number (specified in $limit) of elements from
* $array. The elements are returned in a random order, exactly
* as it was passed to the function. (So, it's safe for multi-
* dimensional arrays, aswell as array's where you need to keep
* the keys)
*
* @author Brendan Caffrey  <bjcffnet at gmail dot com>
* @param  array  $array  The array to return the elements from
* @param  int    $limit  The number of elements to return from
*                            the array
* @return array  The randomized array
*/
function array_rand_keys($array, $limit = 1) {
   
$count = @count($array)-1;

   
// Sanity checks
   
if ($limit == 0 || !is_array($array) || $limit > $count) return array();
    if (
$count == 1) return $array;

   
// Loop through and get the random numbers
   
for ($x = 0; $x < $limit; $x++) {
       
$rand = rand(0, $count);

       
// Can't have double randoms, right?
       
while (isset($rands[$rand])) $rand = rand(0, $count);

       
$rands[$rand] = $rand;
    }

   
$return = array();
   
$curr = current($rands);

   
// I think it's better to return the elements in a random
    // order, which is why I'm not just using a foreach loop to
    // loop through the random numbers
   
while (count($return) != $limit) {
       
$cur = 0;

        foreach (
$array as $key => $val) {
            if (
$cur == $curr) {
               
$return[$key] = $val;

               
// Next...
               
$curr = next($rands);
                continue
2;
            } else {
               
$cur++;
            }
        }
    }

    return
$return;
}
?>
up
0
yhoko at yhoko dot com
10 years ago
According to office at at universalmetropolis dot com I have to say that the example is wrong.

<?php
// retrieve one of the options at random from the array
$teamcolours = $teamcolours[rand(0,count($teamcolours))];
?>

The count() function will return the number of items in the array, that's the last index + 1. So if there's 2 items in the array, count() will return 2 but the indices are 0 and 1. Now since rand(x,y) randomizes between x and y inclusively the index from the above example may be out of bounds. Thus you have to subtract 1 from the count:

<?php
   
// Get random item
   
$teamcolours = $teamcolours[rand(0,count($teamcolours)-1)];
?>
up
-1
Anonymous
2 years ago
It doesn't explicitly say it in the documentation, but PHP won't pick the same key twice in one call.
To Top