Finding the average of elements in ArrayCollection in Symfony, MongoDB

Viewed 325

I have a class of news that has ratings from users. My aim is to find the average of all the ratings, I'm using MongoDB. I tried to find a function already for average built-in but I couldn't find. So I plan on using the count() function and then get the sum of all elements in the array collection and divide sum by count, however, the sum is not working well, is there a built-in function? and if not how can I iterate in a PHP array collection and add the values

 public function __construct()
    {
        $this->positiveFeedback = new ArrayCollection();
        $this->negativeFeedback = new ArrayCollection();
        $this->rating = new ArrayCollection();
    }    

 /**
     * @return Collection|Rating[]
     */
    public function getRating(): Collection
    {
        return $this->rating;
    }

    public function addRating(Rating $rating): self
    {
        if (!$this->rating->contains($rating)) {
            $this->rating[] = $rating;
            $rating->setNews($this);
        }

        return $this;
    }

    public function removeRAting(Rating $rating): self
    {
        if ($this->rating->contains($rating)) {
            $this->rating->removeElement($rating);
            // set the owning side to null (unless already changed)
            if ($rating->getNews() === $this) {
                $rating->setNews(null);
            }
        }

        return $this;
    }
 /**
     * Get the value of RatingAverage
     */ 
    public function getRatingAverage()
    {
        $ratingsNumber =  $this->getRating()->count();
        $ratingSum = $this->getRating()->getValues();

    }

the getRatingAverage is where I'm stuck

1 Answers

No, there's no built-in method to calculate it, but you can transform it into a regular array an use array functions quite easily.

Assuming your Rating class has a property called score:

public function getRatingAverage()
{
    $ratingsNumber = $this->getRating()->count();

    if (0 === $ratingsNumber)
        return;

    $scores = $this->getRating()
        // Get a new collection containing only the score values
        ->map(function($rating) { return $rating->getScore(); })
        // Transform into an array
        ->getValues();

    $ratingSum = array_sum($scores);
    $ratingAvg = $ratingSum / $ratingsNumber;

    return $ratingAvg;
}

However a Collection is iterable, so you can use a regular foreach if you want to loop it.

Reference for the Collectionmethods

Related