How to shuffle a PHP array while keeping the same keys

Summary:

You will need to create a custom iterative or recursive function if you want to shuffle an array while maintaining the same keys. Review the article below with some available use cases.

Shuffle a PHP array while keeping same keys

The shuffle function shuffle a PHP array but does not preserve the key. This article finds a workaround for this problem.

Introduction

We have already seen a couple of articles about how to shuffle an array PHP. These articles feature the PHP shuffle function. This function is pretty helpful and straightforward in shuffling an array. However, it doesn’t preserve the keys. Now, this may not be desirable behavior.

shuffle a PHP array

The image above is an example of how the shuffle function resets the keys. Without these keys, the values are difficult to interpret. For instance, the key gives context about the “8.8”, implying the “IMBDb rating.” So, losing the keys loses the context of the elements in some scenarios.

So this article explores how to shuffle a PHP array while keeping the same keys.

Shuffle a PHP array while keeping same keys

So, we need to have a custom function. Here’s a good implementation.

function shuffle_associate($arr)
{
    $arr_keys = array_keys($arr);
    shuffle($arr_keys);
    $random = [];
 
    foreach($arr_keys as $key)
    {
        $random[$key] = $arr[$key];
    }
 
    return $random;
}

So, this implementation gets the array of keys through array_keys. Instead of shuffling the array, it shuffles the keys array. Next, it initiates an empty random array. The following foreach loop iterates over the keys array and populates the random array.


$random[$key] = $arr[$key];

This statement assigns the values from the original array to the keys in the random array. So, the shuffle happens indirectly. Here’s the output.

OUTPUT
Array
(
    [Genre] => Action/Sci-fi
    [IMDb] => 8.8
    [Title] => Inception
)

Voila! The function shuffles the array and keeps the same keys. Also, it does not mutate the original array instead returns a new array.

Shuffle a PHP multidimensional array while keeping the same keys

We have seen an article about shuffling a multidimensional array. However, the article uses the shuffle function, and as seen already, it does not preserve the keys. So, this section explores a workaround for the multidimensional arrays.

Iteratively shuffle a PHP array

Let’s begin with the iterative approach first. Though the iterative approach has some downsides, sometimes it may be inevitable. So, here’s an iterative example.

function shuffle_iterative(&$arr)
{
    $arr = shuffle_associate($arr);
    foreach($arr as &$v1)
    {
        foreach($v1 as &$v2)
        {
            $v2  = shuffle_associate($v2);
   
        }      
    }
}

The function takes an array by reference. So, it does shuffling in place. Here’s the input array before shuffling.

$arr = [
    "Numbers" =>
    [
        ["1", "2", "3", "4", "5"],
    ],
    "Alphabets" =>
    [
        ["A", "B", "C", "D", "E"],
    ],
    "Emojis"=>
    [
        [":)", ":(", ":P", ":D", ";)"]
    ]
];

Here’s the output after shuffling.

Array
(
    [Alphabets] => Array
        (
            [0] => Array
                (
                    [0] => A
                    [3] => D
                    [2] => C
                    [1] => B
                    [4] => E
                )
 
        )
 
    [Numbers] => Array
        (
            [0] => Array
                (
                    [3] => 4
                    [0] => 1
                    [1] => 2
                    [4] => 5
                    [2] => 3
                )
 
        )
 
    [Emojis] => Array
        (
            [0] => Array
                (
                    [4] => ;)
                    [2] => :P
                    [1] => :(
                    [0] => :)
                    [3] => :D
                )
 
        )
 
)

Voila! It shuffles all the nested elements and does not reset the keys at any level.

Recursively shuffle a PHP array

The recursive approach is always generalized and robust. Here’s a recursive implementation of the custom function.

function shuffle_recursive(&$arr)
{
    $arr = shuffle_associate($arr);
 
    foreach($arr as &$v)
    {
        if(gettype($v) == "array")
        {
            shuffle_recursive($v);
        }
    }
 
}

This function calls shuffle_associate for every array in the nested structure. For your confirmation, here’s the output.

Array
(
    [Emojis] => Array
        (
            [0] => Array
                (
                    [1] => :(
                    [3] => :D
                    [2] => :P
                    [4] => ;)
                    [0] => :)
                )
 
        )
 
    [Alphabets] => Array
        (
            [0] => Array
                (
                    [0] => A
                    [4] => E
                    [3] => D
                    [2] => C
                    [1] => B
                )
 
        )
 
    [Numbers] => Array
        (
            [0] => Array
                (
                    [1] => 2
                    [0] => 1
                    [3] => 4
                    [2] => 3
                    [4] => 5
                )
 
        )
 
)

Perfect! The recursive function works just as we want.

A High School Quiz – A Use Case

Here’s a good scenario to see the usability of what we have seen so far. Here’s an array having questions for a high school quiz.

$quiz = [
    "Geography" => "Which is the longest river in the world?",
    "Biology"   => "What does the human blood contain?",
    "Chemistry" => "What is the chemical formula of water?",
    "Physics"   => "State Newton's third law of motion.",
    "Maths"     => "Find radius of a circle if its diameter is 2 units."
];

We want a program that will shuffle these questions without losing the keys. So, that there’s a lesser chance that two students get the questions in the same order. So, this is very much the scenario where we can use what we have learned.

$shuffled_questions = shuffle_recursive($quiz);
 
$name = readline('Enter your name: ');
 
foreach($shuffled_questions as $k => $v)
{
    echo "Section: ".$k.PHP_EOL;
    echo "Question: ".$v.PHP_EOL;
    $answer = readline('Enter your answer: ');
}
print_r("DONE!");

So the program shuffles the quiz before initiating the test. Here are snapshots of the test for two students.

array PHP

Here is the test for the second student. The sequence of questions changes for him.

shuffle a PHP array

Conclusion

So, the article explores a workaround for shuffling a PHP array while keeping the same keys. It includes a custom function that it subsequently uses for multidimensional arrays. The shuffle function in PHP resets the keys while the custom function here preserves them. Hopefully, this article solves the problem for you. If you want to learn more about PHP, feel free to check out some great articles at FuelingPHP.

Want to learn more about PHP?

We have many fun articles related to PHP. You can explore these to learn more about PHP.


Article Categories

Article Tags

© 2023 Confident.Systems