array_rand

Description

Picks one or more random entries out of an array, and returns the
key (or keys) of the random entries.
It uses a pseudo random number generator that is not suitable for
cryptographic purposes.

Parameters

array

The input array.

num

Specifies how many entries should be picked.

Return Values

When picking only one entry, array_rand() returns
the key for a random entry. Otherwise, an array of keys for the random
entries is returned. This is done so that random keys can be picked
from the array as well as random values. Trying to pick more elements
than there are in the array will result in an
E_WARNING level error, and NULL will be returned.

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.

I agree with Sebmil (http://php.net/manual/en/function.array-rand.php#105265) that "array_rand()" produces weird and very uneven random distribution (as of my local PHP 5.3.8 and my public host's PHP 5.2.17).Unfortunately, I haven't got any access either to a server with the latest PHP version. My info is for those of you who like to check things for themselves and who don't believe all of the official statements in the docs.I've made a simple adjustment of his test code like this:<?php $s=1; // Start value$c=50; // Count / End value$test=array_fill($s, $c, 0);$ts=microtime(true);for($i=0; $i<5000000; $i++){$idx=mt_rand($s, $c); // Try it with rand() - simpler but more evenly distributed than mt_rand()$test[$idx]++;}$te=microtime(true);$te=($te-$ts)*1000.0; // Loop time in miliseconds

And it appears to me that simple "$idx=rand(0, count($test)-1);" is much better than "$idx=array_rand($test, 1);".And what's more the simpler and a bit slower (0 ms up to total 712.357 ms at 5 mln cycles) "rand()" is better than "mt_rand()" in simple everyday use cases because it is more evenly distributed (difference least vs. most often numbers: ca. 0.20-1.28 % for "rand()" vs. ca. 1.43-1.68 % for "mt_rand()").Try it for yourself... although it depends on your software and hardware configuration, range of numbers to choose from (due to random patterns), number of cycles in the loop, and temporary (public) server load as well.

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.

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.

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

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.

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:

It is not written on here but you should note that the keys that are returned are always sorted low to high. This was unexpected for me since my main reason to use this function was to get a random subset of an array (use case was to list products in a sidebar).

As a result of this, even if the same products were picked randomly another time, they were always arranged in the same way.

This is my solution, may help someone who also needs a fully randomized subset of an array:

@Sebmil :You say this function "has a strange randomness [, because] the 31st one is always by far the less occuring (by about 10% less than others)."

That's right (at least under linux, PHP 5.3). And it's also visible when calling array_rand with 1 as second parameter.

After checking the code, and testing it, I concluded that you have to call srand() at each iteration of your loop.

To be simple, a rand() call is made <n> times when the <n>th key is returned;I suppose there is a flaw in the pseudorandom number generator (PRNG) that php uses; somehow the generation has a frequency of 31 (when a random number is sufficiently low, then the 31st after it will be more higher).

Reinitializing the PRNG each time you enter the loop make the problem disappear (and is cheaper, in terms of time, than using shuffle).

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 mysqlmySQL_Select_DB("database"); //..to DB@$potms = MySQL_Query("SELECT * FROM potm"); //now we get all from our table and store itMySQL_Close($link); //there`s no need for connection, so we should close it

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;

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.

if you're looking for a cryptographically secure variant (as of speaking, php uses mt_rand), i made this. (limitations: it has no $num parameter. it requires php>=7)

<?phpfunction csarray_rand(array $arr){$keys=array_keys($arr);$count=count($keys); if($count===0){//Contrary to documentation, PHP 4 and 5 and 7, up to php 7.1.0alpha3 does not actually return any warning when the array is empty and $num=NULL (and further contradicting the documentation, its NULL by default, not 1, and they are treated differently, 1 gives error, NULL does not.) ... 7.1.0beta1 does throw an error however... follow their example?if(version_compare(PHP_VERSION,'7.1.0beta1','>=')){trigger_error('Warning: csarray_rand(): Array is empty',E_USER_ERROR); } return NULL; }$csrand=random_int(0,count($keys)-1); return $keys[$csrand];}?>

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:

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.