Collection::average
Returns the mean of the collection's values, optionally averaging one key or a computed value.
average(callable|string|null $callback = null): float|int|null- Added in Laravel 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$$callbackoptional | (callable(TValue): float|int)|string|null= null | A key to pull from each item, or a closure returning the number to average. Omit it to average the values themselves. |
Return value
float|int|nullThe arithmetic mean of the resolved values, or null when nothing resolved to a non-null value.
Changelog
- PHP 5.2avg() was introduced as the canonical name; average() remains a permanent alias for it.
average() is a straight alias for avg() — identical signature, identical implementation. Use whichever reads better; neither is deprecated.
Three call shapes
With no argument it averages the values themselves. With a string it uses data_get(), so 'total' works on arrays, objects and Eloquent models alike, and dot notation such as 'meta.score' reaches into nesting. With a closure it averages whatever the closure returns, which is how you average a derived figure like $line['qty'] * $line['price'].
Nulls are skipped, not zeroed
This is the behaviour that surprises people. Items resolving to null are excluded from both the sum and the divisor. collect([10, null, 20])->average() is 15, not 10. If a missing value should count as zero, map it first: ->map(fn ($v) => $v ?? 0).
Empty means null
An empty collection — or one where every value resolves to null — returns null, not 0. Echoing that prints an empty string and arithmetic on it triggers a PHP 8.5 deprecation. Use ?? 0 or round($avg ?? 0, 2) before formatting.
Floats
The result is a plain float division, so it carries binary floating-point error. Never compare it with ===; round it, or sum integer cents and divide yourself.
Example
When to use it
- Compute the mean order value across a collection of order rows.
- Average one column of an API response without unpacking it first.
- Average a derived figure such as line quantity multiplied by unit price.
Frequently asked questions
What is the difference between average() and avg() in Laravel collections?
There is none — average() is a permanent alias that calls avg() directly, with the same parameters and the same return value. Pick whichever reads better in your code.
Why does average() return null instead of 0 for an empty collection?
Because the mean of no values is undefined, not zero, so returning 0 would be a false answer. Use ($collection->average() ?? 0) when you need a number to format or add.
How does average() handle null values in the collection?
It ignores them completely, removing them from both the sum and the count of items divided by. Map nulls to 0 first if they should drag the average down.
More examples
Nulls skipped versus nulls counted
The same three rows give 4 or 2.67 depending on how the unrated row is treated. average() excludes nulls from the divisor, so mapping them to zero first is the only way to make them count. When nothing resolves at all the result is null.
<?php
$ratings = collect([
['stars' => 5],
['stars' => 3],
['stars' => null], // never rated
]);
// Skips the null: (5 + 3) / 2
echo $ratings->average('stars'), PHP_EOL;
// 4
// Treats the null as a zero: (5 + 3 + 0) / 3
echo $ratings->map(fn (array $r) => $r['stars'] ?? 0)->average(), PHP_EOL;
// 2.6666666666667
// Every value null -> null, not 0
var_dump(collect([['stars' => null]])->average('stars'));
// NULLAveraging Eloquent models and formatting safely
String keys resolve through data_get(), so model attributes and dotted relation paths both work. Coalescing to 0 before number_format() prevents an empty result set from printing a blank figure, and rounding the float keeps the percentage readable. Needs a booted application with a database.
<?php
$orders = Order::whereMonth('created_at', 3)->get();
// data_get() reads the model attribute, dot notation reaches relations.
$mean = $orders->average('total_cents');
$shipping = $orders->average('shipment.cost_cents');
// null-safe formatting: an empty month must not print an empty string
echo number_format(($mean ?? 0) / 100, 2), PHP_EOL;
// 84.50
// Averaging a derived value
$marginPct = $orders->average(
fn (Order $o) => ($o->total_cents - $o->cost_cents) / $o->total_cents * 100
);
echo round($marginPct ?? 0, 1), '%', PHP_EOL;
// 31.4%
Discussion