2010-11-05 3 views
33

J'ai regardé sur google pour la réponse, mais je n'arrive pas à trouver quelque chose d'infaillible et je ne peux pas vraiment me permettre de tout gâcher (aller vivre dans un site de production).PHP Random Shuffle Array Maintien Clé => Valeur

Ce que j'ai est une recherche avancée avec plus de 20 filtres, ce qui retourne un tableau comprenant un ID et une distance. Ce que je dois faire est de mélanger ces résultats pour les afficher dans un ordre aléatoire à chaque fois. Le tableau que j'ai qui sort en ce moment est:

Array (
    [0] => Array ([id] => 1 [distance] => 1.95124994507577) 
    [1] => Array ([id] => 13 [distance] => 4.75358968511882) 
    [2] => Array ([id] => 7 [distance] => 33.2223233233323) 
    [3] => Array ([id] => 21 [distance] => 18.2155453552336) 
    [4] => Array ([id] => 102 [distance] = 221.2212587899658) 
) 

Ce que je dois être en mesure de faire est de randomiser ou de l'ordre de ceux-ci à chaque fois, mais maintenir les paires id et de distance, à savoir:

Array (
    [4] => Array ([id] => 102 [distance] = 221.2212587899658) 
    [1] => Array ([id] => 13 [distance] => 4.75358968511882) 
    [3] => Array ([id] => 21 [distance] => 18.2155453552336) 
    [2] => Array ([id] => 7 [distance] => 33.2223233233323) 
    [0] => Array ([id] => 1 [distance] => 1.95124994507577) 
) 
Merci :)

Répondre

68

le first user post sous la documentation shuffle:

shuffle sociatif et tableau non associatif tout en préservant paires de valeurs clés. Renvoie également le tableau mélangé au lieu de le mélanger en place.

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

Cas de test:

$arr = array(); 
$arr[] = array('id' => 5, 'foo' => 'hello'); 
$arr[] = array('id' => 7, 'foo' => 'byebye'); 
$arr[] = array('id' => 9, 'foo' => 'foo'); 
print_r(shuffle_assoc($arr)); 
print_r(shuffle_assoc($arr)); 
print_r(shuffle_assoc($arr)); 
+0

J'ai essayé, mais le tableau semble sortir dans le même ordre à chaque fois à l'aide print_r ($ arr) – lethalMango

+0

@lethalMango - ours avec moi, je suis à la recherche dans ça. – karim79

+0

Ok, merci :) – lethalMango

12

À partir de 5.3.0 que vous pourriez faire:

uksort($array, function() { return rand() > rand(); }); 
+0

cela peut ne pas produire un tableau uniformément mélangé en fonction du tri algorithme impliqué – marcusklaas

+0

Le réarrangement des tableaux en triant sur rand() est très lent et donne un shuffle biaisé. – Rich

+1

peut être légèrement amélioré 'uksort ($ array, function() {return rand()> getrandmax()/2});' –

1

Essayez d'utiliser l'algorithme fisher-yates de here:

function shuffle_me($shuffle_me) { 
    $randomized_keys = array_rand($shuffle_me, count($shuffle_me)); 
    foreach($randomized_keys as $current_key) { 
     $shuffled_me[$current_key] = $shuffle_me[$current_key]; 
    } 
    return $shuffled_me; 
} 

J'ai dû mettre en place quelque chose de similaire à cela pour ma thèse de premier cycle, et ça marche très bien.

+2

Salut Jesse, j'ai exactement le même code de script à ma page: fonction shuffle_me (shuffle_me de $) { $ randomized_keys = array_rand (shuffle_me de $, compter (shuffle_me de $)); foreach ($ randomized_keys sous la forme $ current_key) { $ shuffled_me [$ current_key] = $ shuffle_me [$ current_key]; } return $ shuffled_me; } Cela fonctionne parfaitement avec PHP4, mais cela ne fonctionne pas avec PHP5. Je pense que la raison est la modification au journal array_rand: 5.2.10 - Le tableau de clés résultant n'est plus mélangé. Que devrais-je changer pour travailler sur un serveur PHP5? Merci –

4

Jetez un oeil à cette fonction ici:

 $foo = array('A','B','C'); 


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 */`enter code here` 
    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; 
    } 

     shuffle_with_keys($foo); 
     var_dump($foo); 

Original post ici: http://us3.php.net/manual/en/function.shuffle.php#83007

3

j'avais du mal avec la plupart des réponses fournies - donc j'ai créé ce petit bout qui a pris mes tableaux et les randomisés tout en maintenant leurs clés:

function assoc_array_shuffle($array) 
{ 
    $orig = array_flip($array); 
    shuffle($array); 
    foreach($array AS $key=>$n) 
    { 
     $data[$n] = $orig[$n]; 
    } 
    return array_flip($data); 
} 
+0

Fonctionne uniquement pour les valeurs de chaînes et d'entiers non égales (comparaison libre). – hakre

2
function shuffle_assoc($array) 
{ 
    $keys = array_keys($array); 
    shuffle($keys); 
    return array_merge(array_flip($keys), $array); 
} 
+1

Cela ne semble pas fournir de résultats corrects pour les tableaux avec des clés de type entier. – Andy

2

Charles Iliya Krempeaux a une nice writeup sur la question et une fonction qui a fonctionné très bien pour moi:

function shuffle_assoc($array) 
{ 
    // Initialize 
     $shuffled_array = array(); 


    // Get array's keys and shuffle them. 
     $shuffled_keys = array_keys($array); 
     shuffle($shuffled_keys); 


    // Create same array, but in shuffled order. 
     foreach ($shuffled_keys AS $shuffled_key) { 

      $shuffled_array[ $shuffled_key ] = $array[ $shuffled_key ]; 

     } // foreach 


    // Return 
     return $shuffled_array; 
} 
0

J'ai essayé la solution la plus vote n'a pas la liste de lecture aléatoire populaire. C'est le changement que j'ai fait pour le faire fonctionner. Je veux ma clé de tableau à partir de 1.

$list = array_combine(range(1,10),range(100,110)); 
$shuffle_list = shuffle_assoc($list); 


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

    $keys = array_keys($list); 
    shuffle($list); 
    $random = array(); 
    foreach ($keys as $k => $key) { 
     $random[$key] = $list[$k]; 
    } 
    return $random; 
} 
Questions connexes