文字

shuffle

(PHP 4, PHP 5, PHP 7)

shuffle将数组打乱

说明

bool shuffle ( array &$array )

本函数打乱(随机排列单元的顺序)一个数组。

参数

array

待操作的数组。

返回值

成功时返回 TRUE , 或者在失败时返回 FALSE

范例

Example #1 shuffle() 例子

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

更新日志

版本 说明
4.2.0 随机数发生器自动进行播种。

注释

Note: 此函数为 array 中的元素赋与新的键名。这将删除原有的键名,而不是仅仅将键名重新排序。

参见

  • 数组排序函数对比

用户评论:

[#1] xzero at elite7hackers dot net [2015-05-30 13:09:02]

There is an function which uses native shuffle() but preserves keys, and their order, so at end, only values are shuffled.

<?PHP

function array_quake(&$array) {
    if (
is_array($array)) {
        
$keys array_keys($array); // We need this to preserve keys
        
$temp $array;
        
$array NULL;
        
shuffle($temp); // Array shuffle
        
foreach ($temp as $k => $item) {
            
$array[$keys[$k]] = $item;
        }
        return;
    }
    return 
false;
}

// Example
$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";
?>


Result example:
Before (original):
Array
(
    [ZERO] => 0
    [ONE] => 1
    [TWO] => 2
    [THREE] => 3
    [FOUR] => 4
    [FIVE] => 5
    [SIX] => 6
    [SEVEN] => 7
    [EIGHT] => 8
    [NINE] => 9
)

After (Array Quake);
Array
(
    [ZERO] => 4
    [ONE] => 2
    [TWO] => 0
    [THREE] => 8
    [FOUR] => 3
    [FIVE] => 6
    [SIX] => 1
    [SEVEN] => 7
    [EIGHT] => 5
    [NINE] => 9
)

[#2] peter at removethisplease dot ddcrew dot com [2013-12-02 13:55:22]

This seems to do reasonably well as a shuffle() that preserves index assocation:

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


Obviously only works if PHP has closures enabled...

[#3] timtrinidad at gmail dot com [2011-08-08 12:38:32]

It appears that the suhosin extensions >= 0.9.26 that have the suhosin.mt_srand.ignore and suhosin.srand.ignore settings set to "Off" do not affect shuffle().

In other words, the only way I was able to get pseudo-random and predictable results through shuffle() was to disable the extension.

[#4] Eric Anderson [2011-03-29 09:33:55]

Copy and paste this script and refresh the page to see the shuffling effect.

<?php
    

    
    // Create an array of face values
    // and an array of card values
    // then merge them together
    
$cards array_merge(array("J""Q""K""A"), range(2,10)); // 13 cards
    
    // Shuffle the cards
    
shuffle($cards);
    
    
// Create an multidimentional array to hold the 4 suits
    
$suits = array(
        
'Heart' => array(), 
        
'Spade' => array(), 
        
'Diamond' => array(),
        
'Club' => array()
        );
        
    
// Add cards to their respective suits
    
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;";
        }
    }
    
    
// Create a deck
    
$deck = array();
    
    
// Merge the suits into the empty deck array
    
$deck array_merge($deck$suits);
                
    
// Display the deck to the screen
    
echo "<p><b>Deck of cards:</b></p>"
    foreach(
$deck as $k1 => $v1)
    {
        
// Display suit name
        
echo "<p>&emsp;$k1's<br />&emsp;{<br />&emsp;&emsp;";
        
$acc 0;
        
        
// Display card value
        
foreach($v1 as $k2 => $v2)
        {
            echo 
"$v2&nbsp";
            
$acc++;
            
            if (
$acc == 4)
            {
                echo 
"<br />&emsp;&emsp;";
                
$acc 0;
            }
        }
        echo 
"<br />&emsp;}</p>";
    }
?>

[#5] andjones at gmail dot com [2010-08-26 21:35:10]

Shuffle associative and non-associative array while preserving key, value pairs. Also returns the shuffled array instead of shuffling it in place.

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

?>

[#6] ezakto at ezakto dot com [2010-07-24 23:13:38]

This is a replica of shuffle() but preserving keys (associative and non-associative)

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

?>

[#7] m0gr14 at gmail dot com [2010-07-04 10:39:37]

This function shuffles an associative array recursive.

<?php



function rec_assoc_shuffle($array)
{
  
$ary_keys array_keys($array);
  
$ary_values array_values($array);
  
shuffle($ary_values);
  foreach(
$ary_keys as $key => $value) {
    if (
is_array($ary_values[$key]) AND $ary_values[$key] != NULL) {
      
$ary_values[$key] = rec_assoc_shuffle($ary_values[$key]);
    }
    
$new[$value] = $ary_values[$key];
  }
  return 
$new;
}

?>


Example of use:
<?php
$array 
=
    Array(
        
1,
        Array(
            
1,
            
2,
            
3,
            
4,
            Array(
                
1,
                
2,
                
3,
                
4,
                
5
            
)
        ),
        
2,
        
3,
        Array(
            
0,
            
1,
                Array(
                    
1,
                    
2,
                    
3,
                    
4,
                        Array(
                            
1,
                            
6,
                            
5,
                            
2,
                            
1,
                            
3
                        
)
                )
        ),
        
4,
        
5,
        
6,
        
7
    
);
$array rec_assoc_shuffle($array);
echo 
'<pre>';
print_r($array);
echo 
'</pre>';



?>

[#8] rick at suggestive dot com [2010-03-24 14:19:04]

Many people in SEO need to supply an array and shuffle the results and need the same result each time that page is generated. This is my implementation with a working example:

<?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>';
?>

[#9] tyler at CompLangs dot com [2010-01-01 18:59:46]

Here is a quick function I wrote that generates a random password and uses shuffle() to easily shuffle the order. 

<?php
public function randPass($upper 3$lower 3$numeric 3$other 2) {
    
//we need these vars to create a password string
    
$passOrder = Array();
    
$passWord '';

    
//generate the contents of the password
    
for ($i 0$i $upper$i++) {
        
$passOrder[] = chr(rand(6590));
    }
    for (
$i 0$i $lower$i++) {
        
$passOrder[] = chr(rand(97122));
    }
    for (
$i 0$i $numeric$i++) {
        
$passOrder[] = chr(rand(4857));
    }
    for (
$i 0$i $other$i++) {
        
$passOrder[] = chr(rand(3347));
    }

    
//randomize the order of characters
    
shuffle($passOrder);

    
//concatenate into a string
    
foreach ($passOrder as $char) {
        
$passWord .= $char;
    }

    
//we're done
    
return $passWord;
}
?>

[#10] ahmad at ahmadnassri dot com [2009-11-18 20:58:12]

shuffle for associative arrays, preserves key=>value pairs.
(Based on (Vladimir Kornea of typetango.com)'s function) 

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

        
shuffle($keys);

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

        
$array $new;

        return 
true;
    }
?>


*note: as of PHP 5.2.10, array_rand's resulting array of keys is no longer shuffled, so we use array_keys + shuffle.

[#11] Anonymous [2009-08-28 09:18:52]

I needed a simple function two shuffle a two dimensional array. Please note the second level arrays must be indexed using integers, for example $myarray[0]["Name"] and not $myarray["One"]["Name"]. Here is the function:

<?php
function twodshuffle($array)
{
    
// Get array length
    
$count count($array);
    
// Create a range of indicies
    
$indi range(0,$count-1);
    
// Randomize indicies array
    
shuffle($indi);
    
// Initialize new array
    
$newarray = array($count);
    
// Holds current index
    
$i 0;
    
// Shuffle multidimensional array
    
foreach ($indi as $index)
    {
        
$newarray[$i] = $array[$index];
        
$i++;
    }
    return 
$newarray;
}
?>


Please note it only works on two dimensional arrays. Here is an example:

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


?>


Hope you find it useful!

[#12] aalaap at gmail dot com [2009-06-08 05:12:36]

I've been wondering why shuffle() doesn't provide the shuffled array as a return value instead of a bool. I mean, what could possibly go wrong in shuffling elements from an array?

So I use something like this:

<?php
function array_shuffle($array) {
    if (
shuffle($array)) {
        return 
$array;
    } else {
        return 
FALSE;
    }
}
?>

[#13] sivaji2009 at gmail dot com [2009-05-17 14:07:54]

Here i wrote a custom shuffle function which preserves the array index and distributes the array element randomly.

<?php


function custom_shuffle($my_array = array()) {
  
$copy = array();
  while (
count($my_array)) {
    
// takes a rand array elements by its key
    
$element array_rand($my_array);
    
// assign the array and its value to an another array
    
$copy[$element] = $my_array[$element];
    
//delete the element from source array
    
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
)

?>

[#14] dirk dot avery a t gmail [2009-04-30 08:58:42]

Building on examples by m227 and pineappleclock, here is a function that returns all permutations of each set in the power set of an array of strings (instead of a string).  Thanks for the great examples!

<?php



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

[#15] pineappleclock at gmail dot com [2009-01-22 10:06:30]

If you want the Power Set (set of all unique subsets) of an array instead of permutations, you can use this simple algorithm:

<?php

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

[#16] tony at brokerbin dot com [2008-11-11 19:26:06]

Here is IMO the simplest and extremely fast way to shuffle an associative array AND keep the key=>value relationship.  However, it ONLY works if there are NO NUMERIC keys AT ALL.  Look into array_merge for the reason why.

<?php

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

$shuffled array_mergearray_flip(array_rand($unshuffled,count($unshuffled))),$unshuffled );

?>


peace

[#17] Antonio Ognio [2008-05-06 09:42:45]

Another shuffle() implementation that preserves keys, does not use extra memory and perhaps is a bit easier to grasp.

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

[#18] [2006-06-07 14:53:04]

Posted below is code that you would expect to work

<?php

$keys 
shuffle(array_keys($arr));

foreach (
$keys as $key) {

  
$arr_elem $arr[$key];
  
// do what you want with the array element

}

?>


This in fact does not work because shuffle returns a boolean true or false. More accurate code using this method would be:

<?php

$keys 
array_keys($arr);
shuffle($keys);

foreach (
$keys as $key) {

  
$arr_elem $arr[$key];
  
// do what you want with the array element

}

?>

[#19] bill at SWScripts dot com [2005-09-22 09:45:55]

Just a quick note to let people know that shuffle() will work on multidimensional associative arrays provided that the first key is already numeric.

So this array can be shuffled without losing any of the secondary keys or their values:

$array[0]['color'], $array[0]['size'], $array[0]['fabric']
. . .
$array[50]['color'], $array[50]['size'], $array[50]['fabric']

I recently ran up against needing to randomize this array and tried shuffle even though it's not really for associative arrays.

Hope it helps somebody out there.

上一篇: 下一篇: