shuffle

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

shuffle随机排列数组

描述

shuffle(array &$array): true

此函数随机排列(随机化元素在)数组中的顺序。

警告

此函数不会生成密码学安全的随机数,绝不能用于密码学目的,或者需要返回的随机数不可猜测的场合。

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

参数

array

数组。

返回值

始终返回 true

变更日志

版本 描述
7.1.0 内部随机算法 已更改 为使用 » Mersenne Twister 随机数生成器,而不是 libc rand 函数。

示例

示例 #1 shuffle() 示例

<?php
$numbers
= range(1, 20);
shuffle($numbers);
foreach (
$numbers as $number) {
echo
"$number ";
}
?>

注释

注意: 此函数为 array 中的元素分配新的键。它将删除可能已分配的任何现有键,而不是仅重新排列键。

注意:

将数组的内部指针重置为第一个元素。

参见

添加注释

用户贡献注释 16 notes

131
ahmad at ahmadnassri dot com
14 年前
用于关联数组的 shuffle,保留键值对。
(基于 (Vladimir Kornea of typetango.com)'s 函数)

<?php
function shuffle_assoc(&$array) {
$keys = array_keys($array);

shuffle($keys);

foreach(
$keys as $key) {
$new[$key] = $array[$key];
}

$array = $new;

return
true;
}
?>

*注意: 从 PHP 5.2.10 开始,array_rand 生成的键数组不再是随机排列的,所以我们使用 array_keys + shuffle。
26
andjones at gmail dot com
13 年前
在保留键值对的同时随机排列关联数组和非关联数组。也返回随机排列的数组,而不是就地随机排列。

<?php

function shuffle_assoc($list) {
if (!
is_array($list)) return $list;

$keys = array_keys($list);
shuffle($keys);
$random = array();
foreach (
$keys as $key)
$random[$key] = $list[$key];

return
$random;
}

?>
7
匿名
14 年前
我需要一个简单的函数来随机排列二维数组。请注意,第二层数组必须使用整数索引,例如 $myarray[0]["Name"] 而不是 $myarray["One"]["Name"]。以下是该函数

<?php
function twodshuffle($array)
{
// 获取数组长度
$count = count($array);
// 创建一个索引范围
$indi = range(0,$count-1);
// 随机化索引数组
shuffle($indi);
// 初始化新数组
$newarray = array($count);
// 保存当前索引
$i = 0;
// 随机排列多维数组
foreach ($indi as $index)
{
$newarray[$i] = $array[$index];
$i++;
}
return
$newarray;
}
?>

请注意,它只适用于二维数组。以下是一个示例

<?php
$myarray
= array("Google" => array("Name" => "Google", "URL" => "www.google.com", "Usage" => "Googling"), "Yahoo" => array("Name" => "Yahoo", "URL" => "www.yahoo.com", "Usage" => "Yahooing?"), "Ask" => array("Name" => "Ask", "URL" => "www.ask.com", "Usage" => "Asking Jeeves"));

print_r(twodshuffle($myarray));

/* 结果是:
Array ( [0] => Array ( [Name] => Ask [URL] => www.ask.com [Usage] => Asking Jeeves ) [1] => Array ( [Name] => Google [URL] => www.google.com [Usage] => Googling ) [2] => Array ( [Name] => Yahoo [URL] => www.yahoo.com [Usage] => Yahooing? ) )
*/
?>

希望您觉得有用!
9
dirk dot avery a t gmail
15 年前
在 m227 和 pineappleclock 的示例基础上,这里有一个函数可以返回字符串数组(而不是字符串)的幂集中的每个集合的所有排列。感谢您的出色示例!

<?php

/*
使用:$arr = power_perms($in);

示例:
$in = array("A","B","C");
$power_perms = power_perms($in);

返回:
数组
(
[0] => 数组
(
[0] => A
[1] => B
[2] => C
)

[1] => 数组
(
[0] => A
[1] => C
[2] => B
)

[2] => 数组
(
[0] => B
[1] => A
[2] => C
)

[3] => 数组
(
[0] => B
[1] => C
[2] => A
)

[4] => 数组
(
[0] => C
[1] => A
[2] => B
)

[5] => 数组
(
[0] => C
[1] => B
[2] => A
)

[6] => 数组
(
[0] => A
[1] => B
)

[7] => 数组
(
[0] => B
[1] => A
)

[8] => 数组
(
[0] => B
[1] => C
)

[9] => 数组
(
[0] => C
[1] => B
)

[10] => 数组
(
[0] => A
[1] => C
)

[11] => 数组
(
[0] => C
[1] => A
)

[12] => 数组
(
[0] => A
)

[13] => 数组
(
[0] => B
)

[14] => 数组
(
[0] => C
)

)

*/

function power_perms($arr) {

$power_set = power_set($arr);
$result = array();
foreach(
$power_set as $set) {
$perms = perms($set);
$result = array_merge($result,$perms);
}
return
$result;
}

function
power_set($in,$minLength = 1) {

$count = count($in);
$members = pow(2,$count);
$return = array();
for (
$i = 0; $i < $members; $i++) {
$b = sprintf("%0".$count."b",$i);
$out = array();
for (
$j = 0; $j < $count; $j++) {
if (
$b{$j} == '1') $out[] = $in[$j];
}
if (
count($out) >= $minLength) {
$return[] = $out;
}
}

//usort($return,"cmp"); //can sort here by length
return $return;
}

function
factorial($int){
if(
$int < 2) {
return
1;
}

for(
$f = 2; $int-1 > 1; $f *= $int--);

return
$f;
}

function
perm($arr, $nth = null) {

if (
$nth === null) {
return
perms($arr);
}

$result = array();
$length = count($arr);

while (
$length--) {
$f = factorial($length);
$p = floor($nth / $f);
$result[] = $arr[$p];
array_delete_by_key($arr, $p);
$nth -= $p * $f;
}

$result = array_merge($result,$arr);
return
$result;
}

function
perms($arr) {
$p = array();
for (
$i=0; $i < factorial(count($arr)); $i++) {
$p[] = perm($arr, $i);
}
return
$p;
}

function
array_delete_by_key(&$array, $delete_key, $use_old_keys = FALSE) {

unset(
$array[$delete_key]);

if(!
$use_old_keys) {
$array = array_values($array);
}

return
TRUE;
}
?>
4
pineappleclock at gmail dot com
15 年前
如果你想要数组的幂集(所有唯一子集的集合),而不是排列,你可以使用这个简单的算法

<?php
/**
* 返回一维数组的幂集,
* 一个二维数组。
* array(a,b,c) ->
* array(array(a),array(b),array(c),array(a,b),array(b,c),array(a,b,c))
*/
function powerSet($in,$minLength = 1) {
$count = count($in);
$members = pow(2,$count);
$return = array();
for (
$i = 0; $i < $members; $i++) {
$b = sprintf("%0".$count."b",$i);
$out = array();
for (
$j = 0; $j < $count; $j++) {
if (
$b{$j} == '1') $out[] = $in[$j];
}
if (
count($out) >= $minLength) {
$return[] = $out;
}
}
return
$return;
}
?>
6
peter at removethisplease dot ddcrew dot com
10 年前
这看起来像是作为 shuffle() 很好地保留了索引关联

<?php
function ashuffle (&$arr) {
uasort($arr, function ($a, $b) {
return
rand(-1, 1);
});
}
?>

显然只有在 PHP 启用了闭包的情况下才有效...
2
xzero at elite7hackers dot net
9 年前
有一个函数使用 native shuffle(),但保留了键及其顺序,因此最后只对值进行了洗牌。

<?PHP
/**
* 数组地震 - 给数组一个好的地震,这样每个值最终都会得到一个随机的给定空间。
* 键和它们的顺序被保留。
* @author xZero <[email protected]>
* @param array $array
* @return boolean 失败返回 false
*/
function array_quake(&$array) {
if (
is_array($array)) {
$keys = array_keys($array); // 我们需要这个来保留键
$temp = $array;
$array = NULL;
shuffle($temp); // 数组洗牌
foreach ($temp as $k => $item) {
$array[$keys[$k]] = $item;
}
return;
}
return
false;
}

// 例子
$numbers = array(
'ZERO' => 0,
'ONE' => 1,
'TWO' => 2,
'THREE' => 3,
'FOUR' => 4,
'FIVE' => 5,
'SIX' => 6,
'SEVEN' => 7,
'EIGHT' => 8,
'NINE' => 9
);
echo
"\nBefore (original):\n";
print_r($numbers);
array_quake($numbers);
echo
"\n\nAfter (Array Quake);\n";
print_r($numbers);
echo
"\n";
?>

结果示例
Before (original)
数组
(
[ZERO] => 0
[ONE] => 1
[TWO] => 2
[THREE] => 3
[FOUR] => 4
[FIVE] => 5
[SIX] => 6
[SEVEN] => 7
[EIGHT] => 8
[NINE] => 9
)

After (Array Quake);
数组
(
[ZERO] => 4
[ONE] => 2
[TWO] => 0
[THREE] => 8
[FOUR] => 3
[FIVE] => 6
[SIX] => 1
[SEVEN] => 7
[EIGHT] => 5
[NINE] => 9
)
3
tony at brokerbin dot com
15 年前
在我看来,这是最简单、最快的洗牌关联数组并保持键=>值关系的方法。但是,它只有在根本没有数字键的情况下才有效。看一下 array_merge 了解原因。

<?php

$unshuffled
= array('one'=>1,'two'=>2,'three'=>3);

$shuffled = array_merge( array_flip(array_rand($unshuffled,count($unshuffled))),$unshuffled );

?>

和平
4
aalaap at gmail dot com
15 年前
我一直想知道为什么 shuffle() 不提供洗牌后的数组作为返回值,而是布尔值。我的意思是,洗牌数组中的元素有什么可能出错呢?

所以,我使用类似这样的代码

<?php
function array_shuffle($array) {
if (
shuffle($array)) {
return
$array;
} else {
return
FALSE;
}
}
?>
2
ezakto at ezakto dot com
14 年前
这是一个 shuffle() 的复制品,但保留了键(关联和非关联)

bool kshuffle ( array &$array )

<?php

function kshuffle(&$array) {
if(!
is_array($array) || empty($array)) {
return
false;
}
$tmp = array();
foreach(
$array as $key => $value) {
$tmp[] = array('k' => $key, 'v' => $value);
}
shuffle($tmp);
$array = array();
foreach(
$tmp as $entry) {
$array[$entry['k']] = $entry['v'];
}
return
true;
}

$array = array('first' => 0, 'second' => 1, 'third' => 2);
kshuffle($array);
print_r($array); // [second] => 1 [first] => 0 [third] => 2

$array = array('first', 'second', 'third');
kshuffle($array);
print_r($array); // [1] => second [2] => third [0] => first

?>
3
rick at suggestive dot com
14 年前
许多 SEO 人员需要提供一个数组,并对其结果进行洗牌,并且需要每次生成该页面时都获得相同的结果。这是我的实现,包括一个工作示例

<?php
function seoShuffle(&$items,$string) {
mt_srand(strlen($string));
for (
$i = count($items) - 1; $i > 0; $i--){
$j = @mt_rand(0, $i);
$tmp = $items[$i];
$items[$i] = $items[$j];
$items[$j] = $tmp;
}
}

$items = array('one','two','three','four','five','six');
$string = 'whatever';

echo
'<pre>';
print_r($items);
echo
'</pre>';

seoShuffle($items,$string);

echo
'<pre>';
print_r($items);
echo
'</pre>';
?>
2
sivaji2009 at gmail dot com
15 年前
我写了一个自定义的洗牌函数,它保留了数组索引并随机分配数组元素。

<?php

/*
* 返回一个元素以随机顺序排列的数组。
*/
function custom_shuffle($my_array = array()) {
$copy = array();
while (
count($my_array)) {
// 通过其键获取一个随机数组元素
$element = array_rand($my_array);
// 将数组及其值分配给另一个数组
$copy[$element] = $my_array[$element];
// 从源数组中删除该元素
unset($my_array[$element]);
}
return
$copy;
}

$array = array(
'a' => 'apple',
'b' => 'ball',
'c' => 'cat',
'd' => 'dog',
'e' => 'egg',
'f' => 'fan',
'g' => 'gun'
);

print_r(custom_shuffle($array));

Array
(
[
c] => cat
[e] => egg
[f] => fan
[a] => apple
[b] => ball
[g] => gun
[d] => dog
)

?>
2
Eric Anderson
13 年前
复制并粘贴此脚本,然后刷新页面以查看洗牌效果。

<?php
/**
* 洗牌并显示一副牌中的牌
* @author: Eric Anderson
* @filename: deckofcards.php
*/

// 创建一个面值数组
// 和一个牌值数组
// 然后将它们合并在一起
$cards = array_merge(array("J", "Q", "K", "A"), range(2,10)); // 13 张牌

// 洗牌
shuffle($cards);

// 创建一个多维数组来保存 4 种花色
$suits = array(
'Heart' => array(),
'Spade' => array(),
'Diamond' => array(),
'Club' => array()
);

// 将牌添加到它们各自的花色中
for($i = 0; $i < count($suits); $i++)
{
for(
$j = 0; $j < count($cards); $j++)
{
$suits['Heart'][$j] = $cards[$j]."<span style=color:#FF0000;>&hearts;</span>";
$suits['Spade'][$j] = $cards[$j]."&spades;";
$suits['Diamond'][$j] = $cards[$j]."<span style=color:#FF0000;>&diams;</span>";
$suits['Club'][$j] = $cards[$j]."&clubs;";
}
}

// 创建一副牌
$deck = array();

// 将花色合并到空的牌组数组中
$deck = array_merge($deck, $suits);

// 将牌组显示到屏幕上
echo "<p><b>Deck of cards:</b></p>";
foreach(
$deck as $k1 => $v1)
{
// 显示花色名称
echo "<p>&emsp;$k1's<br />&emsp;{<br />&emsp;&emsp;";
$acc = 0;

// 显示牌值
foreach($v1 as $k2 => $v2)
{
echo
"$v2&nbsp";
$acc++;

if (
$acc == 4)
{
echo
"<br />&emsp;&emsp;";
$acc = 0;
}
}
echo
"<br />&emsp;}</p>";
}
?>
2
tyler at CompLangs dot com
14 年前
下面是我编写的一个快速函数,它生成一个随机密码并使用 shuffle() 来轻松地随机排列顺序。

<?php
public function randPass($upper = 3, $lower = 3, $numeric = 3, $other = 2) {
// 我们需要这些变量来创建一个密码字符串
$passOrder = Array();
$passWord = '';

// 生成密码的内容
for ($i = 0; $i < $upper; $i++) {
$passOrder[] = chr(rand(65, 90));
}
for (
$i = 0; $i < $lower; $i++) {
$passOrder[] = chr(rand(97, 122));
}
for (
$i = 0; $i < $numeric; $i++) {
$passOrder[] = chr(rand(48, 57));
}
for (
$i = 0; $i < $other; $i++) {
$passOrder[] = chr(rand(33, 47));
}

// 随机排列字符顺序
shuffle($passOrder);

// 连接成字符串
foreach ($passOrder as $char) {
$passWord .= $char;
}

// 我们完成了
return $passWord;
}
?>
1
Antonio Ognio
16 年前
另一个 shuffle() 实现,它保留了键,不使用额外的内存,可能更容易理解。

<?php
if (function_exists('shuffle_with_keys')===false) {
function
shuffle_with_keys(&$array) {
/* 辅助数组用于保存新顺序 */
$aux = array();
/* 我们使用一个包含键的数组 */
$keys = array_keys($array);
/* 我们打乱键的顺序 */
shuffle($keys);
/* 我们遍历新键的顺序 */
foreach($keys as $key) {
/* 我们以新的顺序插入键值对 */
$aux[$key] = $array[$key];
/* 我们从旧数组中删除元素以节省内存 */
unset($array[$key]);
}
/* 包含新顺序的辅助数组覆盖旧变量 */
$array = $aux;
}
}
?>
0
DiosDe
3 年前
使用 random_int() 实现 shuffle()

<?php

function random_int_shuffle ( array $array ): array
{
$array = array_values($array);

$result = [];
$skip_indexes = [];

$sizeof_array = count($array);

for (
$i = 0; $i < $sizeof_array; $i++ )
{
do
{
$random_index = random_int(0, $sizeof_array);
} while (
in_array($random_index, $skip_indexes) );

$skip_indexes[] = $random_index;
$result[] = $array[$random_index];
}

return
$result;
}
?>
To Top