Filtering of a Doctrine collection

Published on 2022-03-19 • Modified on 2022-03-19

In this snippet, we see how to filter a Doctrine collection. We have this filter() function we can call with a closure. Here I use an arrow function to keep the code concise, just below the same result using array_fitler().


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

use App\Data\ArticleData;
use App\Entity\Tag;
use Doctrine\Common\Collections\Collection;

/**
 * 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.
 *
 * @property ArticleData $articleData
 */
trait Snippet194Trait
{
    public function snippet194(): void
    {
        $snippet = $this->articleData->getSnippetById(194); // this snippet

        /** @var Collection<int, Tag> $tags */
        $tags = $snippet->getTags();

        echo sprintf('There is %d tags associated to the snippet.', $tags->count()).PHP_EOL;

        // now filter tags starting by "array"
        $filtered = $tags->filter(static fn (Tag $tag) => str_starts_with((string) $tag->getName(), 'array'));
        echo sprintf('There is %d tag(s) starting with "array".', $filtered->count()).PHP_EOL;

        // with array_filter()
        $filtered2 = array_filter($tags->toArray(), static fn (Tag $tag) => str_starts_with((string) $tag->getName(), 'array'));
        echo sprintf('There is %d tag(s) starting with "array".', \count($filtered2));

        // That's it! 😁
    }
}

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

<?php

declare(strict_types=1);

namespace App\Tests\Integration\Controller\Snippets;

use App\Data\ArticleData;
use App\Entity\Tag;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @see Snippet194Trait
 */
final class Snippet194Test extends KernelTestCase
{
    private ArticleData $articleData;

    protected function setUp(): void
    {
        $this->articleData = self::getContainer()->get(ArticleData::class);
    }

    /**
     * @see Snippet194Trait::snippet194
     */
    public function testSnippet194(): void
    {
        $snippet = $this->articleData->getSnippetById(194);
        $tags = $snippet->getTags();
        self::assertCount(6, $tags);
        $filtered = $tags->filter(static fn (Tag $tag) => str_starts_with((string) $tag->getName(), 'array'));
        self::assertCount(2, $filtered);
        $filtered2 = array_filter($tags->toArray(), static fn (Tag $tag) => str_starts_with((string) $tag->getName(), 'array'));
        self::assertCount(2, $filtered2);
        /** @var Tag $tag */
        $tag = $filtered->first();
        self::assertTrue(str_starts_with((string) $tag->getName(), 'array'));
    }
}