average(avg) — コレクションの平均値を返す

collection
  • カテゴリ: collection
  • 対応バージョン: Laravel 11・12・PHP 8.2
  • 名前空間 / FQCN: Illuminate\Support\Collection::avg(別名: average)/Illuminate\Support\LazyCollection::avgIlluminate\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(...) のエイリアス

引数(表)

引数必須既定値説明
$callbackcallable | string | nullnullcallable(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

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする