简体   繁体   中英

Shuffling the first level of the array in PHP

PHP's shuffle() is not randomizing an array the way I need it. I have a two dimensional array and when I use shuffle() on it it only randomizes the 2nd dimension of the array, but I need the opposite.

Lets assume this is the array I need to shuffle:

Array
(
    [0] => Array
        (
            [key1] => 199
            [key2] => 6
        )

    [1] => Array
        (
            [key1] => 195
            [key2] => 3
        )

)

The way the shuffle() shuffles it is like this:

Array
(
    [0] => Array
        (
            [key1] => 195
            [key2] => 3
        )

    [1] => Array
        (
            [key1] => 199
            [key2] => 6
        )

)

But this is not what I'm after. What I need as an end result is this:

Array
(
    [1] => Array
        (
            [key1] => 195
            [key2] => 6
        )

    [0] => Array
        (
            [key1] => 199
            [key2] => 6
        )

)

I know that this can be achieved this using a random key with rand() or mt_rand() , but it also could be possible that for a small amount of keys, we could receive the same rand() key twice, leading to NOT have a nicely shuffled array.

I also know that adding more if else logic would be a possibility, but I'm looking to do this with already implemented stuff - I don't wanna reinvent the wheel.

How can I achieve my desired shuffle?

shuffle() is working as intended. It is not "randomizing the 2nd dimension", it is not recursive.

It is reordering the elements of the array (which just happen to be arrays). The issue you are seeing is because shuffle() resets the array's keys.

From the docs ( http://php.net/shuffle ):

Note : This function assigns new keys to the elements in array. It will remove any existing keys that may have been assigned, rather than just reordering the keys.

To get what you want, you need to use array_rand() to randomize the keys, then reorder the elements in the array based on that.

$randKeys = array_rand($array, count($array));
// This is needed because array_rand was changed
// and now returns the keys in order
shuffle($randKeys);

uksort($array, function($a, $b) use($randKeys){
    return array_search($a, $randKeys) - array_search($b, $randKeys);
});

DEMO: https://eval.in/101265

In the comment section of the PHP manual for shuffle you find:

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

    shuffle($keys);

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

    $array = $new;

    return true;
}
?>
$yourArray = array(
    array('key1' => 199, 'key2' => 6),
    array('key1' => 195, 'key2' => 3),
    array('key1' => 205, 'key2' => 8)
);

$helperArr = array();
foreach($yourArray as $subArr)
{
    foreach($subArr as $key => $value)
        $helperArr[$key][] = $value;        
}

foreach($helperArr as &$shuffleArr)
    shuffle($shuffleArr);

$shuffledArr = array();
foreach($helperArr as $key => $value)
{   
    for($i = 0; $i < count($value); $i++)
        $shuffledArr[$i][$key] = $value[$i];        
}

echo '<pre>';
print_r($helperArr);
print_r($shuffledArr);
echo '</pre>';

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM