2010-11-05 9 views
33

Szukałem w Google odpowiedzi, ale nie mogę znaleźć czegoś, co byłoby głupie i nie można sobie pozwolić na zepsucie tego (przejście do miejsca produkcji).Random Shuffle Array PHP Utrzymywanie klucza => Wartość

Co mam to zaawansowane wyszukiwanie z ponad 20 filtrami, które zwraca tablicę zawierającą identyfikator i odległość. Muszę przetasować te wyniki, aby za każdym razem wyświetlać je w losowej kolejności. Tablica mam, że wychodzi w tej chwili jest:

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

Co muszę być w stanie zrobić, to losowo lub kolejność tych każdym czasie, ale utrzymać identyfikator i międzymiastowych parami, tzn:

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

Dzięki :)

Odpowiedz

68

first user post pod dokumentacji shuffle:

Shuffle jako towarzyska i niezespolona tablica przy zachowaniu klucza , par wartości. Zwraca także przetasowaną tablicę zamiast tasowania jej na miejscu . Sprawa

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

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

Próbowałem, ale tablica wydaje się wychodzić w tej samej kolejności za każdym razem używając print_r ($ arr) – lethalMango

+0

@lethalMango - pokrywa się ze mną, szukam w tym. – karim79

+0

OK, dziękuję :) – lethalMango

12

Od 5.3.0 można zrobić:

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

, co może nie generować jednolicie tasowanych tablic w zależności od sortowania Algorytm zaangażowany – marcusklaas

+0

Tasowanie tablic przez sortowanie na rand() jest bardzo powolne i daje stronnicze tasowanie. – Rich

+1

można nieznacznie poprawić 'uksort ($ array, function() {return rand()> getrandmax()/2});' –

1

Spróbuj użyć algorytmu Fisher-Yates od 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; 
} 

Musiałem zaimplementować coś podobnego do mojej licencjatowej pracy magisterskiej i działa bardzo dobrze.

+2

Cześć Jesse, mam dokładnie ten sam kod skryptu na mojej stronie: funkcja shuffle_me ($ shuffle_me) { $ randomized_keys = array_rand ($ shuffle_me, count ($ shuffle_me)); foreach ($ randomized_keys jako $ current_key) { $ shuffled_me [$ current_key] = $ shuffle_me [$ current_key]; } return $ shuffled_me; } Działa doskonale z PHP4, jednak nie działa z PHP5. Myślę, że powodem jest zmiana w dzienniku array_rand: 5.2.10 - Wynikowa tablica kluczy nie jest już tasowana. Co musiałbym zmienić, aby działał na serwerze PHP5? Dzięki –

4

Spójrz do tej funkcji tutaj:

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

oryginalny post tutaj: http://us3.php.net/manual/en/function.shuffle.php#83007

3

miałem trudności z większości udzielonych odpowiedzi - tak stworzyłem ten mały fragment, które miały moje tablice i randomizowanych je zachowując klucze:

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

Działa tylko dla nierównomiernego (luźne porównanie) wartości ciągu i liczby całkowitej. – hakre

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

To wydaje się nie zapewniać poprawnych wyników dla tablic z kluczami całkowitymi. – Andy

2

Charles Iliya Krempeaux ma nice writeup w tej kwestii i funkcji, które naprawdę dobrze dla mnie:

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

Próbowałem rozwiązanie najbardziej popularne głosowanie nie listy odtwarzania losowego. To jest zmiana, którą wprowadziłem, aby to zadziałało. chcę mój klucz tablicy począwszy od 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; 
}