【Laravel】Collectionの使い方完全ガイド|map・filter・reduce・groupByなど実務でよく使うメソッド一覧

2026-04-27

はじめに

Laravelを使っていると、データベースから取得したレコードや配列データを加工する場面が頻繁にあります。

そのときに活躍するのが Collection(コレクション) です。PHPの配列をそのまま操作するより、はるかに読みやすく、メソッドチェーンで直感的に書けるのが特徴です。

この記事では、実務でよく使うCollectionのメソッドを厳選してコード例つきで解説します。

Collectionとは

CollectionはLaravelが提供する配列ラッパークラスです。Illuminate\\Support\\Collection として実装されており、PHPの配列を扱いやすくするための豊富なメソッドが用意されています。

collect() ヘルパ関数を使えば、簡単にCollectionを生成できます。

$collection = collect([1, 2, 3, 4, 5]);

Eloquentのクエリ結果は自動的にCollectionとして返されるため、モデルを使っている場合は意識せず恩恵を受けられます。

$users = User::all(); // Illuminate\\Database\\Eloquent\\Collection

よく使うメソッド一覧

map

各要素を変換して新しいCollectionを返します。元のCollectionは変更されません。

$prices = collect([100, 200, 300]);

$taxed = $prices->map(fn($price) => $price * 1.1);
// [110.0, 220.0, 330.0]

モデルのコレクションに対しても使えます。

$users = User::all()->map(fn($user) => [
    'id'   => $user->id,
    'name' => $user->name,
]);

mapとtransformの違い

transform() は元のCollectionを直接変更します(破壊的操作)。map() は新しいCollectionを返す非破壊的操作です。実務では map() を使うほうが安全です。

filter / reject

条件に合う要素だけを残します。reject() は逆に条件に合う要素を除外します。

$numbers = collect([1, 2, 3, 4, 5, 6]);

$even = $numbers->filter(fn($n) => $n % 2 === 0);
// [2, 4, 6]

$odd = $numbers->reject(fn($n) => $n % 2 === 0);
// [1, 3, 5]

引数なしで呼ぶと nullfalse・空文字など偽値を除外します。

$clean = collect([1, null, 2, false, 3, ''])->filter();
// [1, 2, 3]

each

各要素に対して処理を実行します。戻り値は元のCollectionです。変換ではなく副作用(ログ出力・メール送信など)に使います。

$users->each(function ($user) {
    Log::info("User: {$user->name}");
});

false を返すとループを中断できます。

$collection->each(function ($item) {
    if ($item > 3) {
        return false; // ループ中断
    }
    echo $item;
});

pluck

特定のキー(カラム)の値だけを取り出します。

$users = collect([
    ['name' => 'Alice', 'age' => 30],
    ['name' => 'Bob',   'age' => 25],
]);

$names = $users->pluck('name');
// ['Alice', 'Bob']

第2引数にキーを指定すると、連想配列として取得できます。

$users = User::all()->pluck('name', 'id');
// [1 => 'Alice', 2 => 'Bob', ...]

groupBy

指定したキーでグループ化します。

$orders = collect([
    ['status' => 'pending',   'amount' => 100],
    ['status' => 'completed', 'amount' => 200],
    ['status' => 'pending',   'amount' => 150],
    ['status' => 'completed', 'amount' => 300],
]);

$grouped = $orders->groupBy('status');

// [
//   'pending'   => [['status' => 'pending', 'amount' => 100], ...],
//   'completed' => [['status' => 'completed', 'amount' => 200], ...],
// ]

クロージャを使えば動的なグループ化も可能です。

$grouped = $orders->groupBy(fn($order) => $order['amount'] >= 200 ? 'high' : 'low');

reduce

要素を畳み込んで単一の値を返します。合計・最大値・カスタム集計など柔軟に使えます。

$total = collect([100, 200, 300])->reduce(fn($carry, $item) => $carry + $item, 0);
// 600

第2引数は初期値です。省略すると最初の要素が初期値になります。

chunk

Collectionを指定サイズに分割します。大量データをバッチ処理するときに便利です。

$chunks = collect([1, 2, 3, 4, 5])->chunk(2);
// [[1, 2], [3, 4], [5]]

$chunks->each(function ($chunk) {
    // バッチ処理
});

sortBy / sortByDesc

指定キーでソートします。

$users = collect([
    ['name' => 'Charlie', 'age' => 28],
    ['name' => 'Alice',   'age' => 30],
    ['name' => 'Bob',     'age' => 25],
]);

$sorted = $users->sortBy('age');
// Bob(25), Charlie(28), Alice(30)

$sorted = $users->sortByDesc('age');
// Alice(30), Charlie(28), Bob(25)

first / last

条件に合う最初・最後の要素を返します。

$users = collect([
    ['name' => 'Alice', 'age' => 30],
    ['name' => 'Bob',   'age' => 25],
    ['name' => 'Carol', 'age' => 35],
]);

$youngest = $users->sortBy('age')->first();
// ['name' => 'Bob', 'age' => 25]

$oldest = $users->sortBy('age')->last();
// ['name' => 'Carol', 'age' => 35]

引数にクロージャを渡すと条件付きで取得できます。

$adult = $users->first(fn($user) => $user['age'] >= 30);
// ['name' > 'Alice', 'age' > 30]

contains / doesntContain

指定した値や条件が含まれるか確認します。

$numbers = collect([1, 2, 3, 4, 5]);

$numbers->contains(3);       // true
$numbers->doesntContain(10); // true

$users->contains('name', 'Alice'); // true
$users->contains(fn($u) => $u['age'] > 40); // false

unique

重複を除去します。

$tags = collect(['php', 'laravel', 'php', 'mysql', 'laravel']);

$unique = $tags->unique();
// ['php', 'laravel', 'mysql']

キーを指定すれば、そのキーの値で重複判定します。

$users->unique('email');

count / sum / avg / min / max

集計系メソッドです。

$prices = collect([100, 200, 300, 400]);

$prices->count(); // 4
$prices->sum();   // 1000
$prices->avg();   // 250.0
$prices->min();   // 100
$prices->max();   // 400

キーを指定することもできます。

$orders->sum('amount');
$orders->avg('amount');

実務でよく使うパターン

APIレスポンスの整形

$users = User::all()->map(fn($user) => [
    'id'    => $user->id,
    'name'  => $user->name,
    'email' => $user->email,
])->values(); // インデックスをリセット

条件フィルタリング後の集計

$totalRevenue = Order::all()
    ->filter(fn($order) => $order->status === 'completed')
    ->sum('amount');

グループ化して件数を取得

$statusCounts = Order::all()
    ->groupBy('status')
    ->map(fn($group) => $group->count());

// ['pending' => 5, 'completed' => 12, 'cancelled' => 2]

pluckでIDリストを生成してIN句に使う

$categoryIds = Category::where('active', true)->pluck('id');

$products = Product::whereIn('category_id', $categoryIds)->get();

Lazyコレクションとの使い分け

通常のCollectionはすべての要素をメモリに展開してから処理します。数万件以上のデータを扱う場合は LazyCollection を使うことでメモリを節約できます。

// 通常のCollection:全件メモリに載る
$users = User::all()->filter(...);

// LazyCollection:1件ずつ処理
User::cursor()->filter(...)->each(function ($user) {
    // 処理
});
CollectionLazyCollection
データ取得全件一括1件ずつ(カーソル)
メモリ使用多い少ない
向いている場面少量データ・加工大量データ・ストリーム処理

cursor() はEloquentのクエリに対して使え、PDOのカーソルで1件ずつフェッチします。

まとめ

LaravelのCollectionを使いこなすことで、PHPの配列操作より可読性が高く、バグの少ないコードが書けるようになります。

メソッド用途
map各要素を変換する
filter / reject条件で絞り込む
each副作用の処理を実行
pluck特定カラムを取り出す
groupByグループ化
reduce畳み込み集計
chunk分割してバッチ処理
sortBy / sortByDescソート
first / last先頭・末尾を取得
contains存在確認
unique重複除去
count / sum / avg集計

まずは mapfilterpluckgroupBy の4つを使いこなすことを目指してみてください。実務の大半のケースはこの4つで対応できます。

LaravelLaravel,PHP

Posted by 千原 耕司