whereIn — 指定キーの値が配列に含まれる要素だけを抽出

  • カテゴリ: collection
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: Illuminate\Support\Collection::whereIn
  • 関連: where / whereStrict / whereInStrict / whereNotIn / filter
  • 変更履歴: ―

要点(TL;DR)

  • 配列(候補値)のいずれかに一致する要素だけを非破壊で絞り込み
  • 最低限の使い方:$users->whereIn('status', ['active','pending']);
    • 比較は緩やか(==)。厳密比較は whereInStrict
    • キーは保持される(必要なら values() で振り直し)
    • クエリビルダの whereIn と異なりメモリ上で実行(大量件数は注意)

概要

コレクション中の各要素から指定キーの値を取り出し、その値が与えた配列に含まれるものだけを残します。where が「単一値との等価」を見るのに対し、whereIn は「複数候補のいずれか」を手早く表現できます。Eloquent 取得後の軽い絞り込みや、API レスポンスの後処理に有用です。

構文 / シグネチャ

Collection whereIn(string|int $key, array $values);
  • 引数
引数必須既定値説明
$keystring|int取り出すキー。dot 記法でネスト可(例: user.role
$valuesarray許可する値の配列
  • 戻り値Illuminate\Support\Collection(元コレクションを変更しない新インスタンス)
  • 例外/副作用:例外なし。内部で data_get() によりプロパティ/配列アクセス

カテゴリ別の要点(collection)

  • チェーン可否: 可
  • 破壊的/非破壊: 非破壊
  • キー保持: 保持(必要なら values()
  • LazyCollection: 対応(遅延評価で O(n) 逐次)
  • 計算量の目安: O(n)(in_array 相当)

入出力対応(小さなサンプル)

入力要素values出力(キー保持)
['id'=>10,'status'=>'active']['active','pending']残る
['id'=>11,'status'=>'disabled']['active','pending']除外
['id'=>12,'status'=>'pending']['active','pending']残る

使用例

最小例

<?php

use Illuminate\Support\Collection;

$users = collect([
    ['id' => 1, 'name' => 'A', 'status' => 'active'],
    ['id' => 2, 'name' => 'B', 'status' => 'disabled'],
    ['id' => 3, 'name' => 'C', 'status' => 'pending'],
]);

$visible = $users->whereIn('status', ['active', 'pending']);

// 結果: id 1 と 3(キー 0,2 を保持)

実務例(ネスト・キー振り直し・厳密比較)

<?php

use Illuminate\Support\Collection;

// 受注データを API から取得した配列と仮定
$orders = collect([
    ['no' => 'A001', 'customer' => ['country' => 'JP'], 'total' => 5000],
    ['no' => 'A002', 'customer' => ['country' => 'US'], 'total' => 12000],
    ['no' => 'A003', 'customer' => ['country' => 'FR'], 'total' => 8000],
]);

// 対象国の受注のみ
$target = $orders
    ->whereIn('customer.country', ['JP', 'US']) // dot 記法でネスト抽出
    ->values();                                 // 連番キーに振り直し

// 厳密比較が必要なとき(例:'0' と 0 を区別)
$strict = $orders->whereInStrict('customer.country', ['JP']);

大量データの注意(DB側でやるべきケース)

<?php

use App\Models\User;

// 悪手:全件を取得してからメモリで絞る
$ng = User::all()->whereIn('status', ['active','pending']);

// 推奨:SQL の whereIn で絞り込み(DB最適化の恩恵を受ける)
$ok = User::query()->whereIn('status', ['active','pending'])->get();

よくある落とし穴・注意

  • 緩やかな等価whereIn は緩やか比較(==)相当。型を区別したい場合は whereInStrict
  • キー保持:フィルタ後も元のキーが残る。連番配列が必要なら values()
  • スカラ配列には不向き:要素自体がスカラ値のコレクションでは $key が取れない。filter(fn($v)=>in_array($v,$values,true)) を使用。
  • パフォーマンス:大量件数は DB 側 whereIn を優先。コレクション版は取得後の後処理向け。
  • null マッチ$valuesnull を含めると、キー未定義/値が null の要素もヒットし得る。明示的に避けたい場合は事前に除外。

代替・関連APIとの比較

  • where:単一値との等価。候補が複数なら whereIn が簡潔。
  • whereInStrict:型まで一致必須(===)。ID・フラグの厳密比較に。
  • whereNotIn / whereNotInStrict:逆条件(候補に含まれないもの)。
  • filter:自由条件。複合ロジックや範囲条件に有利。
  • クエリビルダ whereIn:DB で実行。大量件数ではこちらを使う。

テスト例(Pest)

<?php

use Illuminate\Support\Collection;

it('filters by whereIn and keeps keys', function () {
    $items = collect([
        10 => ['role' => 'admin'],
        11 => ['role' => 'user'],
        12 => ['role' => 'guest'],
    ]);

    $filtered = $items->whereIn('role', ['admin', 'user']);

    expect($filtered->keys()->all())->toBe([10, 11])
        ->and($filtered->pluck('role')->all())->toBe(['admin', 'user']);
});

it('uses strict comparison when requested', function () {
    $items = collect([
        ['flag' => 0],
        ['flag' => '0'],
        ['flag' => 1],
    ]);

    $loose  = $items->whereIn('flag', ['0']);      // 0 と '0' が一致しがち
    $strict = $items->whereInStrict('flag', ['0']); // '0' のみ

    expect($loose)->toHaveCount(2)
        ->and($strict)->toHaveCount(1);
});

トラブルシュート(エラー別)

症状/エラー原因対処
結果が空になる$key の綴り/ネストが誤りdata_get($item, 'customer.country') でデバッグし実在確認
期待より多くヒットする緩やか比較により ‘0’ と 0 などが一致whereInStrict を使用
並び順が崩れたキー保持により想定外の順序で扱っているvalues()->sortBy(...) などで整形
JSON 文字列を比較して一致しない値が JSON 文字列・配列で型不一致事前に型変換し、whereInStrict を使う

参考リンク

レン (Wren)

こんにちは。レンです。

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

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

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

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

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

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