array_rand

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

array_rand从数组中随机选取一个或多个键

描述

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

从数组中随机选取一个或多个条目,并返回随机条目的键(或键)。

注意

此函数不会生成密码学安全的数值,不能用于加密目的,或需要返回不可猜测的值的目的。

如果需要密码学安全的随机性,可以使用 Random\RandomizerRandom\Engine\Secure 引擎。对于简单的用例,random_int()random_bytes() 函数提供了方便且安全的 API,它由操作系统的 CSPRNG 支持。

参数

array

输入数组。不能为空。

num

指定要选取的条目数量。必须大于零,且小于或等于 array 的长度。

返回值

仅选取一个条目时,array_rand() 返回随机条目的键。否则,返回随机条目的键数组。这样做是为了能够从数组中选取随机键,以及选取随机值。如果返回多个键,它们将按照在原始数组中出现的顺序返回。

错误/异常

如果 array 为空,或 num 超出范围,则抛出 ValueError

变更日志

版本 描述
8.0.0 如果 num 超出范围,array_rand() 现在会抛出 ValueError;之前会发出 E_WARNING,并且函数返回 null
8.0.0 如果 array 为空,array_rand() 现在会抛出 ValueError;之前会发出 E_WARNING,并且函数返回 null
7.1.0 内部随机化算法 已更改 为使用 » Mersenne Twister 随机数生成器,而不是 libc rand 函数。

示例

示例 #1 array_rand() 示例

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

参见

添加备注

用户贡献备注 7 个备注

匿名
14 年前
如果数组元素是唯一的,并且都是整数或字符串,以下是一个从数组 $array 中随机选取 $n 个*值*(而不是键)的简单方法:

<?php array_rand(array_flip($array), $n); ?>
匿名
12 年前
文档中没有明确说明,但 PHP 不会在一次调用中选取同一个键两次。
grzeniufication
6 年前
<?php

/**
* 用额外检查包装 array_rand 调用
*
* TLDR; 没有你期望的那么随机。
*
* 注意:对于 n 参数,越接近输入数组的长度,输出越不随机。
* 例如:array_random($a, count($a)) == $a 将返回 true
* 这肯定与用于使数组随机化的方法有关(参见其他评论)。
*
* @throws OutOfBoundsException - 如果 n 小于 1 或超过输入数组的大小
*
* @param array $array - 要随机化的数组
* @param int $n - 要返回的元素数量
* @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)]);
}
grzeniufication
6 年前
<?php
// 从 array_rand 中获取多个值的示例
$a = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ];
$n = 3;

// 如果要获取多个值,可以尝试以下方法:
print_r( array_intersect_key( $a, array_flip( array_rand( $a, $n ) ) ) );

// 如果要重新索引键,请将调用包装在“array_values”中:
print_r( array_values( array_intersect_key( $a, array_flip( array_rand( $a, $n ) ) ) ) );
fulachan2 at gmail dot com
2 年前
array_rand () 获取随机值,但无法回溯其选择的随机值。
一个简单的例子
我决定混合一个包含 10 个条目的数组以检索 3 个值。这个选择将给出递增的随机值。

$myarray = range(1,10);

$pm = array_rand($myarray,3);
// $pm 返回 array(0->0,1->6,2->8)

但如果我决定对一个包含 10 个条目的数组进行洗牌以获得 10 个条目,array_rand () 将选择为每个返回值分配一个值,因此返回值数组将不会是随机的。

$gm = array_rand($myarray,count($myarray));
// $gm 不是随机的 array(0->0,1->1,2->2,3->3,4->4,5->5,6->6,7->7,8->8,9->9)

获取真正随机值的简便方法
要么在循环中每次使用 array_rand () 获取 1 个值

$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);

------------------
或者简单地使用 shuffle () 来真正随机地对数组进行洗牌。
divinity76+spam at gmail dot com
2 年前
对于加密安全版本,请尝试

<?php

/**
* 从数组中获取随机键,使用加密安全的 rng
* 在 https://codereview.stackexchange.com/questions/275832/cryptographically-secure-version-of-the-core-array-rand-function/ 中讨论和审查
*
* @param array $array
* @throws ValueError 如果数组为空
* @return int|string 键
*/
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";
}

?>
(这是一个改进的版本,与第一个版本不同,它避免了复制 *所有* 键)
Vitaly
2 年前
在权重数组中生成随机索引。
Vose 别名方法的实现。

<?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];
}
}

// 用法:

$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