Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to find and element by spec in an arraycollection

Assuming I have two entities:

  • entity A: locations
  • entity B: images

one location owns several images ( one-to-many ). The images might have a property type. I often come to a use case, where i need to filter images by type. At the moment I do it through lifecycle callbacks like you'll see in the following example:

    /**
     * This functions sets all images when the entity is loaded
     *
     * @ORM\PostLoad
     */
    public function onPostLoadSetImages($eventArgs)
    {
        $this->recommendedForIcons = new ArrayCollection();
        $this->whatYouGetImages    = new ArrayCollection();

        foreach ($this->getImages() as $image) {

            if ('background-image' === $image->getType()->getSlug()) {
                $this->backgroundImage = $image;
            } elseif ('product-icon' === $image->getType()->getSlug()) {
                $this->mainIcon = $image;
            } elseif ('product-image' === $image->getType()->getSlug()) {
                $this->productImage = $image;
            } elseif ('recommended-icon' === $image->getType()->getSlug()) {
                $this->recommendedForIcons->add($image);
            } elseif ('what-you-get-image' === $image->getType()->getSlug()) {
                $this->whatYouGetImages->add($image);
            } elseif ('productshoot-fullcolour' === $image->getType()->getSlug()) {
                $this->productImageFullColor = $image;
            } elseif ('product-overview' === $image->getType()->getSlug()) {
                $this->productOverviewImage = $image;
            }

        }

    }

I am wondering if it is possible to search for an element in a doctrine array collection and not for the key or the element itself only.

Thank you.

like image 422
smartius Avatar asked Oct 28 '25 10:10

smartius


2 Answers

You can filter an ArrayCollection with a callback function. As Example, you can implements a method in your entity like:

 public  function  getWhatYouGetImages()
 {
    return $this->getImages()->filter(
        function ($image)  {
            return  ('what-you-get-image' === $image->getType()->getSlug());
        }
    );
}

I suggest to take a look at Doctrine Criteria also, as described in this answer. I can't propose an example for this because I don't know about the getType()->getSlug() on the Image entity.

Hope this help

like image 104
Matteo Avatar answered Oct 30 '25 10:10

Matteo


The ArrayCollection class has a filter method that takes a predicate (a closure) as an argument. That means you can do this:

$predicate = function($image){
    'background-image' === $image->getType()->getSlug()    
}

$images = $this->getImages();
$elements = $images->filter($predicate);

$elements holds now all elements from images that satisfy the predicate.

Internally it does something very similar to your solution; loop all elements and checks the callback...

like image 37
Wilt Avatar answered Oct 30 '25 11:10

Wilt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!