- カテゴリ: collection
- 対応バージョン: Laravel 11・12・PHP 8.2
- 名前空間 / FQCN:
Illuminate\Support\Collection::avg(別名:average)/Illuminate\Support\LazyCollection::avg/Illuminate\Support\Enumerable::avg - 関連:
sum/median/mode/pluck/ クエリビルダのavg - 変更履歴: 特になし
要点(TL;DR)
- 数値(またはキー/コールバックで得た数値)の平均値を返す。空なら
null。 - 例:
collect([10, 20, 30])->avg(); // 20 - 罠:空コレクションは null/非数値が混ざると結果が意図せず 0 寄り/巨大データはDB側の
avg()を使うべき
概要
avg / average はコレクション内の数値の平均を返します。配列・オブジェクトから特定キーを指定したり、コールバックで変換してから平均を取れます。大規模データはコレクションにロードせず、クエリビルダの avg() でDB側集計が推奨です。
構文 / シグネチャ
avg(callable|string|null $callback = null): float|int|null
// average(...) は avg(...) のエイリアス
引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| $callback | callable | string | null | null | callable(item): numeric または キー名("price" や "user.score" など)。未指定なら要素自体を数値として平均。 |
- 戻り値:
float|int|null(要素が空ならnull) - 例外/副作用:例外は通常なし。非数値が混在すると内部の合計計算が 0 扱いになるケースがあり、意図しない平均となる可能性あり。
使用例
最小例
use Illuminate\Support\Collection;
$avg = collect([10, 20, 30])->avg(); // 20
キー指定 / ネストキー
$orders = collect([
['total' => 1200],
['total' => 800],
['total' => 1000],
]);
$avg = $orders->avg('total'); // 1000
$users = collect([
['profile' => ['score' => 72]],
['profile' => ['score' => 88]],
]);
$avgNested = $users->avg('profile.score'); // 80
コールバック指定
$products = collect([
['price' => '1200'],
['price' => '800'],
['price' => '1000'],
]);
$avg = $products->avg(fn ($p) => (int) $p['price']); // 1000
Eloquentコレクション
$avgTotal = \App\Models\Order::paid()->get()->avg('total'); // モデルの属性で平均
LazyCollection(大きなストリーム)
use Illuminate\Support\LazyCollection;
$avg = LazyCollection::make(function () {
for ($i = 1; $i <= 1_000_000; $i++) yield $i;
})->avg(); // 500000.5
よくある落とし穴・注意
- 空コレクションは
null:0 ではない。UI表示時はnullハンドリング必須。 - 非数値の混在:
'abc'等が混じると合計が 0 扱いになり平均が歪むことがある。明示的キャストやfilter(is_numeric)を併用。 - 巨大データはDBで集計:
Model::where(...)->avg('col')やDB::table(...)->avg('col')を使用。メモリ節約・ネットワーク転送量削減。 - チェーン不可:戻り値はスカラー。後続のコレクション操作はできない(
pipe()で受け渡しは可)。 - 計算量:O(n)。LazyCollection でも全走査は必要。
代替・関連APIとの比較
sum:合計。平均が欲しいならsum()/count()でも可だが、空時nullの扱いなどを自前で調整する必要あり。median/mode:中央値・最頻値。外れ値に強い統計が必要ならmedian、代表値を知りたいならmode。- クエリビルダの
avg:DB側で集計。大量レコードは最優先でこちら。コレクションavgはアプリ側計算。
テスト例(Pest)
use Illuminate\Support\Collection;
it('calculates average of numbers', function () {
expect(collect([10, 20, 30])->avg())->toBe(20);
});
it('returns null for empty collection', function () {
expect(collect()->avg())->toBeNull();
});
it('averages by key', function () {
$orders = collect([['total' => 1200], ['total' => 800]]);
expect($orders->avg('total'))->toBe(1000);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
平均が 0 に近い | 非数値文字列が混在し 0 扱い | filter(is_numeric)、またはコールバックで (float) 明示キャスト |
null が返る | コレクションが空 | デフォルト値でフォールバック:$avg ?? 0 等 |
| メモリ不足 | 大量データを get() してから平均 | DB::table(...)->avg('col')/Model::query()->avg('col') を使用 |
| 想定より小数が多い/少ない | 型の混在(int/float)や丸め方 | round($avg, 2) 等でUI側丸めを統一 |
collection 追加事項
- チェーン可否:不可(スカラー返却)
- 破壊的/非破壊:非破壊
- キー保持:該当なし(集計のため)
- LazyCollection:対応(全要素を一度は走査)
- 入出力対応表
| 入力 | 指定 | 出力 |
|---|---|---|
[10, 20, 30] | なし | 20 |
[['v'=>1], ['v'=>3]] | 'v' | 2 |
[['p'=>'100'], ['p'=>'200']] | fn($x)=>(int)$x['p'] | 150 |

