2010-11-05 9 views
33

He estado buscando en Google la respuesta, pero parece que no puedo encontrar algo a prueba de tontos y no puedo permitirme arruinar esto (entrar en un sitio de producción).Matriz de aleatorización aleatoria PHP Mantener clave => Valor

Lo que tengo es una búsqueda avanzada con más de 20 filtros, que devuelve una matriz que incluye una identificación y una distancia. Lo que tengo que hacer es mezclar estos resultados para mostrarlos en orden aleatorio todo el tiempo. La matriz tengo que sale en este momento es:

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

Lo que necesito para ser capaz de hacer es asignar al azar o el orden de estos cada vez, pero mantener los pares id y distancia, es decir:

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

Gracias :)

Respuesta

68

el first user post bajo la documentación shuffle:

shuffle sociative y matriz no asociativa conservando clave, pares de valores. También devuelve matriz arrastrada en lugar de arrastrarla en su lugar. caso

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

prueba:

$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

lo he intentado, pero la matriz parece salir de la misma cada orden usando print_r ($ matriz) – lethalMango

+0

@lethalMango - oso conmigo, estoy buscando en ello. – karim79

+0

Ok, gracias :) – lethalMango

12

A partir de 5.3.0 que podría hacer:

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

esto puede no producir una matriz uniformemente mezclada según la clasificación Algoritmo involucrado – marcusklaas

+0

Al mezclar arreglos ordenando en rand() es muy lento y da una mezcla aleatoria sesgada. – Rich

+1

puede mejorarse ligeramente 'uksort ($ array, function() {return rand()> getrandmax()/2});' –

1

Trate de usar el algoritmo de 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; 
} 

Tuve que implementar algo similar a esto para mi tesis de grado, y funciona muy bien.

+2

Hola Jesse, tengo exactamente el mismo código de script en mi página: función 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; } Funciona perfectamente con PHP4, sin embargo, no funciona con PHP5. Creo que la razón es el cambio en el array_rand log: 5.2.10 - La matriz resultante de claves ya no se baraja. ¿Qué tendría que cambiar para trabajar en un servidor PHP5? Gracias –

4

Echa un vistazo a esta función aquí:

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

Post original aquí: http://us3.php.net/manual/en/function.shuffle.php#83007

3

que estaba teniendo un momento difícil con la mayoría de las respuestas suministradas - así que creé este pequeño fragmento que tuvo mis arrays y los asignados al azar, manteniendo sus claves:

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

Solo funciona para valores de cadena y enteros no iguales (comparación flexible). – hakre

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

Esto no parece proporcionar resultados correctos para matrices con claves enteras. – Andy

2

Charles Iliya Krempeaux tiene un nice writeup sobre el tema y una función que funcionó muy bien para mí:

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

Probé la solución más votos no lo hizo muy popular lista aleatoria. Este es el cambio que hice para que funcione. Quiero que mi clave de la matriz a 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; 
} 
Cuestiones relacionadas