How to shuffle a multidimensional array in PHP

Summary:

The shuffle function only applies to top-level arrays. You should create a recursive function if you need to shuffle a multi-dimensional array.

Shuffle a multidimensional array

The shuffle function does not shuffle a multidimensional array. It shuffles the arrays at the topmost level and ignores the nested arrays. The articles explore a workaround for this problem.

Shuffle Multidimensional Array Code Snippet

// We'll use a recursive function to shuffle
// a multidimensional array. It'll continuously dig
// deeper into the array to shuffle each element.

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

$sampleArray = ["a" => ["b", "c", "d"], 0 => [1, 2, 3]];

shuffle_recursive($sampleArray);

echo $sampleArray;

Introduction

Arrays are frequently used data structures. It can store multiple values, usually of mixed types depending on implementation. There are loads of array functions for retrieving and manipulating array values. One cool feature is that shuffling or randomizing an array. But why shuffle an array?

A use case for shuffling an array could be modeling rolling dice or shuffling cards. A similar article, “How to shuffle an array of objects in PHP”, includes an example of a “Quiz Game” that uses the PHP shuffle function. The example perfectly explains why shuffling is necessary to induce randomization, chance, or luck factor in a program.

This article goes a step further to answer how to shuffle a multidimensional array in PHP. It also includes a use case inspired by the classical Pacman game. Before coming up with a clear example for this query, let’s recap the PHP shuffle function. 

PHP Shuffle(): Shuffle a multidimensional array

shuffle(array &$array): bool

The shuffle function in PHP takes an array by reference, shuffling the elements in place. Here’s an example of this function.

$arr = ["First", "Second", "Third", "Fourth", "Fifth"];
print_r($arr);
 
/*
OUTPUT BEFORE SHUFFLING
Array
(
    [0] => First
    [1] => Second
    [2] => Third
    [3] => Fourth
    [4] => Fifth
)
*/

Here’s the output after shuffling.

shuffle($arr);
print_r($arr);
 
/*
OUTPUT AFTER SHUFFLING
Array
(
    [0] => Fourth
    [1] => Third
    [2] => First
    [3] => Fifth
    [4] => Second
)
*/

So, the function is straightforward. But it shuffles the elements at the root level in an array. What if there’s a multidimensional array like the one below.

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

Calling the shuffle function just shuffles the elements at the top level while the nested arrays remain intact. Here’s the output after shuffling this array.

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

So, what’s the workaround for this problem? The following section explores potential solutions.

Shuffle a multidimensional array in PHP

Iteratively shuffle a multidimensional array

An iterative approach is not generalized for a multidimensional array. The nesting increases as the levels in an array go up. So, one nested loop is good for a 2D array but won’t cover a 3D array. An iterative approach is feasible for 2D arrays. However, as the nesting increases, the code performance falls.

Here’s an example of iteratively shuffling an array.

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

Here’s the output.

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

Recursively shuffle a multidimensional array

The recursive approach is robust because it reaches from root to leaves in an array regardless of its depth. A good solution is always robust and generalized. So, here’s a recursive function that shuffles a multidimensional array.

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

Here’s the output after using this recursive function.

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

Voila! It shuffles elements in the nested arrays as well. 

The Pacman

The Pacman is a classical 2D game featuring a character in a maze. The goal is to eat all of the dots placed in the maze. This game is a good use case for shuffling a multidimensional array. A multidimensional array represents the maze. The example here just models the maze rendering functionality.

shuffle a multidimensional array

Every time a player starts a new game, the program should call a render method. The render method calls a shuffling method in turn. Here’s how the array looks.

$maze = [
    [
        ['.','.','.','*','.','.'],
        ['.','*','.','.','.','*'],
        ['.','.','*','.','.','.'],
        ['*','.','.','.','.','*'],
        ['.','.','.','*','.','*'],
        ['.','*','.','.','.','.'],
    ]
];

Here’s the render() method.

function render(&$maze)
{
    shuffle_recursive($maze);
}


The render() lays out a different maze for every player.

Maze for Player#1
[
    [ ., ., ., ., ., *],
    [ ., ., ., ., *, .],
    [ *, ., *, ., ., .],
    [ ., ., *, ., *, .],
    [ ., ., *, ., ., .],
    [ *, *, ., ., ., .],
]
 
Maze for Player#2
[
    [*, *, ., ., ., .],
    [., ., ., *, ., .],
    [., ., ., ., *, *],
    [., ., ., ., *, .],
    [., ., ., *, ., .],
    [., ., ., *, *, .],
]

So, the shuffle function accomplished a crucial functionality of the Pacman classic.

Conclusion

This article explores how to shuffle a multidimensional array in PHP. The article starts with a recap of the PHP shuffle function. The shuffle function works at the topmost level, not the root level. The article finds an iterative and recursive workaround for shuffling a multidimensional array. Moreover, the article includes an example of the classical Pacman game as a use case.
Hope you like this article. FuelingPHP has loads of interesting and informative PHP content. Stay tuned to learn more.

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

© 2022 Confident.Systems