Shuffle array elements by rearranging the key value associations PHP's shuffle() function destroys the array keys, so I decided to write a shuffle function that doesn't do that and instead rearranges key-value associations. As I would be using the function in place of shuffle() most of the time, I'd like it to be as fast and memory efficient (if a time-space tradeoff is needed, I think I would prioritise time) as possible:

&lt;?
    function swap(&amp;$a, &amp;$b)
    {
        $tmp = $a;
        $a = $b;
        $b = $tmp;
    }

    function shuffleX(&amp;$arr)    #Shuffles the key-value associations in an array.
    {
        $keys = array_keys($arr);   #extract the keys from the array.
        $length = count($keys);
        $i = 0; #Index.
        while ($i &lt; $length-1) 
        {
            $target = rand(($i+1), $length-1);  #This ensures that no value ends up mapped to the same key.
            swap($arr[$keys[$i]], $arr[$keys[$target]]);    #Swap each element of the array with another.
            $i++;
        }
    }
?&gt;
Rather than making iterated rand() calls, you should randomize the data once for best efficiency.  To do this, just isolate the keys, shuffle them, then rejoin the values to the appropriate keys in the new order.

Code: (Demo)

function preserve_shuffle(&amp;$arr)    #Shuffles the key-value associations in an array.
{
    $keys = array_keys($arr);   #extract the keys from the array.
    shuffle($keys);
    for ($index = 0, $length = count($keys); $index &lt; $length; ++$index) {
        $result[$keys[$index]] = $arr[$keys[$index]];
    }
    $arr = $result;
}

$arr = ["a" =&gt; "apple", "b" =&gt; "banana", "c" =&gt; "capsicum", "d" =&gt; "dill"];
preserve_shuffle($arr);
var_export($arr);


Or, if you prefer greater brevity or a functional syntax, you could use the following inside your custom function:

$keys = array_keys($arr);   #extract the keys from the array.
shuffle($keys);
$arr = array_merge(array_flip($keys), $arr);


Proof that it also works: https://3v4l.org/eLMo6



My earlier snippets only reorder the associative data.  The following will shuffle the associations without shuffling the key orders.  It does not guarantee that all initially associations will be destroyed -- which I feel is beneficial / less predictable in a randomized result.

function random_disassociate(&amp;$assoc_array)
{
    if (sizeof($assoc_array) &lt; 2) {
        return;  // data cannot be disassociated
    }
    $keys = array_keys($assoc_array);
    shuffle($assoc_array);
    $assoc_array = array_combine($keys, $assoc_array);
}

$arr = ["a" =&gt; "apple", "b" =&gt; "banana", "c" =&gt; "capsicum", "d" =&gt; "dill"];
random_disassociate($arr);
var_export($arr);