Laravel 5 Collections: Calculating the Average Value of a Collection With avg

Laravel 5 Collections: Calculating the Average Value of a Collection With avg

Laravel 5

The avg method is a useful method for calculating the average of all items in the collection. The avg method defines an optional $key parameter, which can be used to specify what property of the collection should be averaged. If no key is provided, the method assumes the collection contains numeric values and will average all items of the collection. If a key is provided, the method will look for a matching array key or object property on all items in the array and then average the value of those items.

Signature

public function avg(
    $callback = null
);

Example Use

For example, the following code will a new Collection instance and calculate the average of all items in the collection:


// Calculate the average of some array. $average = collect([5, 10, 15, 20])->avg();

After the above code has executed $average would contain the value 12.5, which is the average of 5, 10, 15, and 20.

The previous example was fairly simple, and in most cases the collections will be more complicated. For example, consider the following sample collection of products:


$products = collect([ ['name' => 'Shiny New Tablet', 'price' => 799.99], ['name' => 'Not A Stylus (Digital Stylus)', 'price' => 99.99] ]);

We can calculate the average price of all items in the collection by simply passing in a value for the $key parameter. The value of $key must correspond to some key or property of the nested arrays or objects:

// Calculate the average price of all products.
$averagePrice = $products->avg('price');

After the above code has been executed, the $averagePrice variable would contain the value 449.99.

The avg method will also work on collections of objects, and is used exactly the same way. If we created a new collection of products, where all the individual products are objects instead of nested arrays, we will get the same result:


// Create a new collection where all the items // are objects instead of nested arrays // using the `map` method to convert. $objectProducts = $products->map(function($item, $key) { // Cast each product array into an object. return (object)$item; });

Now we can call the avg method on our new $objectProducts collection:

// Calculate the average price of all products.
$objectAveragePrice = $objectProducts->avg('price');

Like before, the value of $objectAveragePrice would contain the value 449.99.

Averaging Nested Collections

The avg method will also work on nested array items or object properties. You can specify which nested property to average by using "dot" notation.

For example, in the following array of products it is still possible to use the avg method to calculate the average product price:


// Create a new collection with nested // product details. $nestedProductsDetails = collect([ [ 'name' => 'Shiny New Tablet', 'details' => [ 'price' => 799.99 ] ], [ 'name' => 'Not A Stylus (Digital Stylus)', 'details' => [ 'price' => 99.99 ] ] ]); // Calculate the average product price by // supplying the `$key` using "dot" // notation. $averageProductPrice = $nestedProductDetails ->avg('details.price');

As with all the previous examples, the $averageProductPrice variable would contain the value 449.99.

Using avg With Higher Order Messages

The avg method can also be used with higher order messaging, which allows us to invoke collection methods and access object instance properties using PHP's property accessors syntax. In the reject section, we created a Product class that was used to reject all products that were not on sale.

We will, again, take advantage of higher order messages to easily calculate the average price on a collection of Product instances:

$products = collect([
    [
        'name'   => 'Office Chair',
        'price'  => 399.99,
        'onSale' => false
    ],
    [
        'name'   => 'Desk',
        'price'  => 199.34,
        'onSale' => true
    ]
])->transform(function ($item) {
    $product = new Product;
    $product->name = $item['name'];
    $product->price = $item['price'];
    $product->onSale = $item['onSale'];

    return $product;
});

$averagePrice = $products->avg->price;

After the above example has executed, the $averagePrice variable would hold the value 299.665.

Start the Discussion

Leave a comment

Subscribe to our newsletter