PHP
downloads | documentation | faq | getting help | mailing lists | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

sizeof> <rsort
Last updated: Fri, 14 Nov 2008

view this page in

shuffle

(PHP 4, PHP 5)

shuffleMistura os elementos de um array

Descrição

bool shuffle ( array &$array )

Essa função mistura de forma aleatória os elementos de um array.

Parâmetros

array

O array.

Valor Retornado

Retorna TRUE em caso de sucesso ou FALSE em falhas.

Exemplos

Exemplo #1 Exemplo da shuffle()

<?php
$numbers 
range(1,20);
srand((float)microtime()*1000000);
shuffle($numbers);
foreach (
$numbers as $number) {
    echo 
"$number ";
}
?>

Notas

Nota: Esta função define novas chaves para os elementos em array . Ela irá remover qualquer chave que você tenha definido, ao invés de simplesmente reordenar as chaves.

Nota: A partir do PHP 4.2.0, não é mais necessário semear o gerador de números aleatórios com srand() ou mt_srand() pois isso é feito automaticamente.



sizeof> <rsort
Last updated: Fri, 14 Nov 2008
 
add a note add a note User Contributed Notes
shuffle
tony at brokerbin dot com
11-Nov-2008 07:26
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_merge( array_flip(array_rand($unshuffled,count($unshuffled))),$unshuffled );

?>

peace
Antonio Ognio
06-May-2008 09:42
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) {
   
/* Auxiliary array to hold the new order */
   
$aux = array();
   
/* We work with an array of the keys */
   
$keys = array_keys($array);
   
/* We shuffle the keys */
   
shuffle($keys);
   
/* We iterate thru' the new order of the keys */
   
foreach($keys as $key) {
     
/* We insert the key, value pair in its new order */
     
$aux[$key] = $array[$key];
     
/* We remove the element from the old array to save memory */
     
unset($array[$key]);
    }
   
/* The auxiliary array with the new order overwrites the old variable */
   
$array = $aux;
  }
}
?>
rich at home dot nl
23-Jan-2008 09:17
Function that does the same as shuffle(), but preserves key=>values.
(Based on (Vladimir Kornea of typetango.com)'s function)

<?php
 
function shuffle_assoc(&$array) {
    if (
count($array)>1) { //$keys needs to be an array, no need to shuffle 1 item anyway
     
$keys = array_rand($array, count($array));

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

     
$array = $new;
    }
    return
true; //because it's a wannabe shuffle(), which returns true
 
}

 
$test = array(1=>'one','two'=>'2',3=>'3');
 
print_r($test);
 
shuffle_assoc($test);
 
print_r($test);

?>

Array
(
    [1] => one
    [two] => 2
    [3] => 3
)
Array
(
    [two] => 2
    [1] => one
    [3] => 3
)
carrox at mail dot ru
23-Dec-2007 02:15
Very fast way to shuffle associative array and keep key=>value

<?php

  $tmp
=array("one"=>1,"two"=>2,"three"=>3,"four"=>4);
 
$new=array();
 
$c=count($tmp);

 
$k=array_keys($tmp);
 
$v=array_values($tmp);

   while(
$c>0) {
    
$i=array_rand($k);
    
$new[$k[$i]]=$v[$i];
     unset(
$k[$i]); #exlude selected number from list
    
$c--;
   }

  
print_r($tmp);
  
print_r($new);

?>


Result:

Array
(
    [one] => 1
    [two] => 2
    [three] => 3
    [four] => 4
)
Array
(
    [two] => 2
    [three] => 3
    [four] => 4
    [one] => 1
)

And thats all, folks!
downforme at gmx dot at
06-Nov-2007 10:08
my approach to bring some chaos to associative arrays
<?php
define
("SHUFFLEBOTH", 0);
define ("SHUFFLEVALUES", 1);
define ("SHUFFLEKEYS", 2);
function
shuffle_assoc(&$array, $mode=SHUFFLEBOTH) {
   
$keys = array_keys($array);
   
$values = array_values($array);
    if ((
$mode==SHUFFLEBOTH) || ($mode==SHUFFLEVALUES)) shuffle($values);
    if ((
$mode==SHUFFLEBOTH) || ($mode==SHUFFLEKEYS)) shuffle($keys);
   
$array = array_combine($keys, $values);
}
?>
hauser dot j at gmail dot com
14-Feb-2007 02:19
Permutation using recursion

<?php
function perm($n)
{
    if(
$n <= 1) return 1;
    else return
$n * perm($n-1);
}
?>

Usage example:
<?php $result = perm(8); ?>

$result will be 40320
m227 at tlen dot pl
13-Oct-2006 03:22
here come my three pennies about permutations. I did function below to work with word anagrams, it works flawlessly, however may be seen as a slow one.

<?php
/** (c) on LGPL license 2006.10 michal@glebowski.pl */
function fact($int){
   if(
$int<2)return 1;
   for(
$f=2;$int-1>1;$f*=$int--);
   return
$f;
}

/** @return string string $s with $n-th character cut */
function del($s, $n) {
    return
substr($s, 0, $n).substr($s, $n+1);
}
/**
 * @param $s string word to permute
 * @param $n int n-th permutation 
 * @return string n-th permutation (out of strlen(string)!)
 */ 
function perm($s, $n = null) {

    if (
$n === null) return perms($s);

   
$r = '';
   
$l = strlen($s);
    while (
$l--) {
       
$f = fact($l);
       
$p = floor($n/$f);
       
$r.= $s{$p};
       
$s = del($s, $p);
       
$n-= $p*$f;
    }
   
$r.=$s;
    return
$r;
}
/** @return array array of all permutations */
function perms($s) {
   
$p = array();
    for (
$i=0;$i<fact(strlen($s));$i++)    $p[] = perm($s, $i);
    return
$p;
}
?>
07-Jun-2006 02:53
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

}

?>
alejandro dot garza at itesm dot mx
10-Mar-2006 08:47
This is taken from an O'Reilly Book and modified slightly to return all possible permutations of a 1D array:

<?php

# Modified from http://linuxalpha1.eicn.ch/OReilly_books/books/webprog/pcook/ch04_26.htm
# Takes a non-associatuve 1D (vector) array of items
#  and returns an array of arrays with each possible permutation
function array_2D_permute($items, $perms = array( )) {
static
$permuted_array;
    if (empty(
$items)) {
       
$permuted_array[]=$perms;
       
#print_r($new);
      #print join(' ', $perms) . "\n";
   
}  else {
        for (
$i = count($items) - 1; $i >= 0; --$i) {
            
$newitems = $items;
            
$newperms = $perms;
             list(
$foo) = array_splice($newitems, $i, 1);
            
array_unshift($newperms, $foo);
            
array_2D_permute($newitems, $newperms);
         }
         return
$permuted_array;
    }
}

$arr=array("Architecture","Mexico","Periodicals","Test");
$result=array_2D_permute($arr);
print_r($result);
?>
bill at SWScripts dot com
22-Sep-2005 09:45
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.
Markus of CodeWallah.Com
30-Aug-2005 10:55
Here's a pretty little function to shuffle an associative array, taking a bit different approach from the earlier entries.

<?PHP
function ass_array_shuffle ($array) {
    while (
count($array) > 0) {
       
$val = array_rand($array);
       
$new_arr[$val] = $array[$val];
        unset(
$array[$val]);
    }
    return
$new_arr;
}
?>

In the function above, the original array is randomly scavenged upon until nothing is left of it. This removes the need for any temporary variables, or indeed for any superfluous tossing around of stuff.
skissane at iips dot mq dot edu dot au
06-Jun-2005 03:11
note that in PHP 5.0.4 (and assumably earlier versions as well), shuffle internally calls rand(), not mt_rand().

This was important because I was trying to use a fixed seed to get repeatable results, by calling mt_srand(). But of course that doesn't work, since shuffle uses rand() not mt_rand(). The solution is either to use srand() for seeding, or to write your own version of shuffle() using mt_rand(). (See examples which others have contributed; or, just have a look at ext/standard/array.c) mt_rand on many platforms gives better results than the builtin library anyway...

N.B. Obviously, the way the shuffle function is implemented may change without notice in future versions, including e.g. changing to use mt_rand instead.
monte at ohrt dot com
21-Mar-2005 02:10
[EDIT by danbrown AT php DOT net: As pointed out on 25 July, 2008, by "Anonymous", this implementation may have some errors or inconsistencies that may cause this function not to achieve the desired result.  "Anonymous" provided the following link for more information: http://en.wikipedia.org/wiki/Fisher-Yates_shuffle]

This is an attempt to get the Fisher Yates shuffle right, and as optimized as possible. The array items are stepped through from last to first, each being swapped with another between itself and the beginning of the array (N-1 shuffles required.) Using list() to swap array vars instead of a tmp var proved to be slightly slower. Testing for $i = $j decreases performance as the array size increases, so it was left out (elements are always swapped.)

<?php
function fisherYatesShuffle(&$items)
{
   for (
$i = count($items) - 1; $i > 0; $i--)
   {
     
$j = @mt_rand(0, $i);
     
$tmp = $items[$i];
     
$items[$i] = $items[$j];
     
$items[$j] = $tmp;
   }
}
?>
Bjorn AT smokingmedia DOT com
23-Sep-2004 05:02
To shuffle an associated array and remain the association between keys and values, use this function:

<?php

$test_array
= array("first" => 1,"second" => 2,"third" => 3,"fourth" => 4);

function
shuffle_assoc($input_array){

   foreach(
$input_array as $key => $value){
     
$temp_array[$value][key] = $key;
      }

  
shuffle($input_array);

   foreach(
$input_array as $key => $value){
     
$return_array[$temp_array[$value][key]] = $value;
      }

   return
$return_array;
   }

echo
"<pre>";
print_r(shuffle_assoc($test_array));
echo
"</pre><hr />";

// this will output something like this:
/*
Array
(
    [fourth] => 4
    [second] => 2
    [third] => 3
    [first] => 1
)

*/
?>
Justin Knoll
15-Apr-2004 05:24
This code is very appealing in its simplicity and speed, but it's not a random shuffle:

<?php
function randomcmp($a, $b)
{
  return
mt_rand(-1, 1);
}

function
swapshuffle(&$array)
{
 
srand((double) microtime() * 10000000);
 
uksort($array, "randomcmp");
}
?>

This is because uksort calls the C function zend_qsort and this quicksorts the array using the provided comparision function. The pairs of indices selected are biased by the nature of the quicksort algorithm.

One effect is that an element in the middle of the array is heavily biased toward being "shuffled" to the middle. Elements on the edges are biased towards the edges; they're likely to switch edges, but unlikely to end up in the middle.
injunjoel
11-Mar-2004 07:27
Be aware that when shuffling an associative array your associative keys will be lost! example below:
<?php
echo "before shuffle\n";
$numbers = array('first'=>1,'second'=>2,'third'=>3,'fourth'=>4);
foreach(
$numbers as $key=>$value){
    echo
"$key => $value\n";
}
echo
"\nafter shuffle\n";
srand((float)microtime() * 1000000);
shuffle($numbers);

foreach(
$numbers as $key=>$value){
    echo
"$key => $value\n";
}

?>
--output--
before shuffle
first => 1
second => 2
third => 3
fourth => 4

after shuffle
0 => 4
1 => 1
2 => 3
3 => 2

sizeof> <rsort
Last updated: Fri, 14 Nov 2008
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites