Creating a "n" dimensions matrix with PHP

Published on 2022-01-01 • Modified on 2022-01-01

This snippet shows how to create to a "n" dimensions matrix with PHP. In the previous snippet, we saw how to create a two dimensions array; this time, we use a recursive function to create a multi-dimensional array with a desired depth as an argument. Of course, the 2-dimensional case is easy to create manually, but with three or more, it becomes more challenging. That's where the recursive function comes in help. If you have a problem visualizing the produced array, check out the unit tests. It will be much more easier to understand. 😉


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

/**
 * I am using a PHP trait to isolate each snippet in a file.
 * This code should be called from a Symfony controller extending AbstractController (as of Symfony 4.2)
 * or Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Services are injected in the main controller constructor.
 */
trait Snippet182Trait
{
    /**
     * @noinspection PhpRedundantOptionalArgumentInspection
     * @noinspection ArgumentEqualsDefaultValueInspection
     */
    public function snippet182(): void
    {
        $matrix2 = $this->createMatrix(startIndex: 1, dimensions: 2, defaultValue: '');
        $matrix3 = $this->createMatrix(startIndex: 1, dimensions: 3, defaultValue: null);

        var_dump($matrix2);
        var_dump($matrix3);

        echo 'OK';

        // That's it! 😁
    }

    /**
     * @return array<mixed>
     */
    private function createMatrix(int $startIndex = 1, int $dimensions = 2, mixed $defaultValue = '', ?int $iterations = null): array
    {
        if ($iterations === null) {
            $iterations = $dimensions;
        }

        if ($iterations <= 1) {
            return array_fill($startIndex, $dimensions, $defaultValue);
        }

        return array_fill($startIndex, $dimensions, $this->createMatrix($startIndex, $dimensions, $defaultValue, $iterations - 1));
    }
}

 Run this snippet  ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫  More on Stackoverflow   Read the doc  Random snippet

  Work with me!

<?php

declare(strict_types=1);

namespace App\Tests\Integration\Controller\Snippets;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @see Snippet182Trait
 */
final class Snippet182Test extends KernelTestCase
{
    /**
     * @see Snippet181Trait::snippet181
     *
     * @noinspection PhpRedundantOptionalArgumentInspection
     * @noinspection ArgumentEqualsDefaultValueInspection
     */
    public function testSnippet181(): void
    {
        /** @var array{1: array<string>, 2:array<string>} $matrix2 */
        $matrix2 = $this->createMatrix(startIndex: 1, dimensions: 2, defaultValue: '');
        self::assertCount(2, $matrix2);
        self::assertCount(2, $matrix2[1]);
        self::assertCount(2, $matrix2[2]);
        self::assertSame('', $matrix2[2][1]);

        /** @var array{1: array<array<string>>, 2:array<array<string>>, 3:array<array<string>>} $matrix3 */
        $matrix3 = $this->createMatrix(startIndex: 1, dimensions: 3, defaultValue: null);
        self::assertCount(3, $matrix3);
        self::assertCount(3, $matrix3[1]);
        self::assertCount(3, $matrix3[2]);
        self::assertCount(3, $matrix3[3]);
        self::assertCount(3, $matrix3[1][1]);
        self::assertCount(3, $matrix3[1][2]);
        self::assertCount(3, $matrix3[1][3]);
        self::assertNull($matrix3[1][3][1]);
    }

    /**
     * @return array<mixed>
     */
    private function createMatrix(int $startIndex = 1, int $dimensions = 2, mixed $defaultValue = '', ?int $iterations = null): array
    {
        if ($iterations === null) {
            $iterations = $dimensions;
        }

        if ($iterations <= 1) {
            return array_fill($startIndex, $dimensions, $defaultValue);
        }

        return array_fill($startIndex, $dimensions, $this->createMatrix($startIndex, $dimensions, $defaultValue, $iterations - 1));
    }
}