- カテゴリ: collection
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::intersect - 関連: diff / intersectByKeys / unique / filter / whereIn
- 変更履歴: Laravel 5系から存在。Laravel 12 でも基本仕様は同じ(Stillat)
要点(TL;DR)
- 何に使うか:2つの配列/コレクションの「共通して含まれる値」だけを取り出す。
- 最低限の使い方:
$result = collect([1, 2, 3])->intersect([2, 3, 4]); - よくある罠
- キーは元のコレクションのまま 保持される(0,1,2…に振り直されない)
- 「値」で比較するメソッドであり、「キー」は無視される
- 巨大なデータで多用するとメモリ・CPUを食う(DBクエリで絞れるなら whereIn を優先)(Laravel)
概要
intersect は、コレクションと別の配列/コレクションの**積集合(共通部分)**を返すメソッドです。
Eloquent コレクションに対しても同じように使え、特定の ID 群や別クエリ結果との共通レコードだけを取り出すときに便利です。(Laravel)
計算は PHP の array_intersect と同様に行われ、新しいコレクションインスタンスとして結果が返されます。(Stillat)
構文 / シグネチャ
use Illuminate\Support\Collection;
/**
* @param \Illuminate\Support\Collection|array $items
* @return \Illuminate\Support\Collection
*/
public function intersect($items);
引数
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| items | array | Illuminate\Support\Collection | ✔ | なし | 共通部分を取りたい相手側の配列/コレクション |
戻り値
- 型:
Illuminate\Support\Collection- 元のコレクションと
items両方に含まれる値だけを持つ新しいコレクション - キーは「元のコレクション側」のキーが保持される(Stillat)
- 元のコレクションと
例外 / 副作用
- 例外
itemsに配列でもコレクションでもない値を渡すと、PHP の型エラー(TypeError)になる可能性あり。
- 副作用
- 元のコレクションは変更されない(コレクションは基本的に不変)(Laravel)
使用例
最小例
use Illuminate\Support\Collection;
$collection = collect(['one', 'two', 'three', 'four', 'five']);
$result = $collection->intersect(['two', 'five', 'six']);
// $result は以下のようなコレクション
// collect([
// 1 => 'two',
// 4 => 'five',
// ]);
twoとfiveが両方に含まれているため残る- キー
1と4は 元のコレクションのキー がそのまま残る(itsolutionstuff.com)
実務例:Eloquent コレクションで ID リストと突き合わせる
use App\Models\User;
// なんらかの条件で取得したユーザー一覧
$users = User::where('active', true)->get();
// 通知対象として許可されたユーザーID
$allowedUserIds = [1, 5, 8, 13];
// 「アクティブユーザー」かつ「許可リストにも含まれる」ユーザーだけに絞り込む
$targetUsers = $users->intersect(
User::whereIn('id', $allowedUserIds)->get()
);
// $targetUsers は Eloquent\Collection のまま
foreach ($targetUsers as $user) {
// 通知処理など
}
intersectに渡す側も Eloquent コレクションなので、モデルインスタンス同士の共通部分が取れる(Laravel)
実務例:タグIDの共通部分で記事を絞る(IDのコレクション同士)
use App\Models\Post;
// 記事A・記事Bに紐づくタグID一覧を取得
$postA = Post::findOrFail(10);
$postB = Post::findOrFail(20);
$tagIdsA = $postA->tags->pluck('id'); // コレクション
$tagIdsB = $postB->tags->pluck('id'); // コレクション
// 共通タグIDだけ取り出す
$commonTagIds = $tagIdsA->intersect($tagIdsB)->values();
// 共通タグを持つ他の記事を探す
$relatedPosts = Post::whereHas('tags', function ($q) use ($commonTagIds) {
$q->whereIn('tags.id', $commonTagIds);
})->get();
values()でキーを振り直しておくと、そのままwhereInに渡しやすい
よくある落とし穴・注意
- キーが保持される
- 0 からの連番にしたい場合は
->values()を追加する。
- 0 からの連番にしたい場合は
- 「値」だけで比較される
- キーは比較に使われない。キーでの共通部分を取りたい場合は
intersectByKeysを使う。(itsolutionstuff.com)
- キーは比較に使われない。キーでの共通部分を取りたい場合は
- ゆるい比較であることに注意
- 内部的には PHP の
array_intersect相当の処理で、'1'と1は同じとみなされる挙動になる。 - 型まで区別したい場合は、あらかじめ型を揃えるか、独自のフィルタロジック(
filter+in_array(..., true))を実装する。
- 内部的には PHP の
- 巨大コレクションには不向き
- 何万件ものモデルコレクション同士を
intersectするより、DB レベルでwhereInや JOIN を使って絞る方が性能面で有利。
- 何万件ものモデルコレクション同士を
代替・関連APIとの比較
diff($items)intersectの逆で、「相手側に存在しない値」を返す。除外フィルターに向いている。(Laravel)
intersectByKeys($items)- 「キー」で積集合を取る。連想配列的なデータ(設定配列など)でキー単位の共通部を取りたいときはこちら。(itsolutionstuff.com)
unique()- 片側のコレクション内で重複を削除する。2つの集合間の比較ではなく、単一集合の整理に使う。(Laravel)
- Eloquent クエリビルダの
whereIn()- DBクエリ時点での絞り込み。大量データの場合はこちらを優先し、
intersectは「メモリ上の小さなセットの整形」に限定すると安全。(Laravel)
- DBクエリ時点での絞り込み。大量データの場合はこちらを優先し、
選定基準としては:
- DBから取る前に絞れるか? → 可能なら
whereInなどクエリで対応 - すでに2つのコレクションが手元にあるか? → 値ベースなら
intersect、キーならintersectByKeys - 除外したいか? →
diff
テスト例(Pest)
use Illuminate\Support\Collection;
it('returns intersection of two collections', function () {
$a = collect([10, 20, 30, 40]);
$b = collect([20, 40, 50]);
$result = $a->intersect($b);
expect($result->all())->toBe([
1 => 20,
3 => 40,
]);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
| 結果が常に空コレクションになる | 片方の集合に含まれる値の型や値が微妙に違っている | 比較対象の配列・コレクションの中身と型を確認し、必要に応じてキャスト(map(fn ($v) => (int)$v)など)する |
| 期待と違うキー(0,1,2…)にならない | intersect は元のコレクションのキーを保持する | ->values() でキーを振り直す |
implode や json_encode すると想定外の順序になる | キーが飛び飛びのままだと、順序を前提にした処理が崩れる | sort() や values() で順序・キーを調整した上で後続処理を行う |
| 大量データで処理が遅い・メモリを多く消費している | 巨大なコレクション同士をメモリ上で比較している | 事前に DB クエリで集約・絞り込みを行い、intersect は小さい集合に限定する |
参考リンク
- Laravel 12.x Collections — Official Documentation (Laravel)
- Laravel 12.x Eloquent Collections — Official Documentation (Laravel)
- Laravel Collection Public API: intersect — Stillat (Stillat)
- Laravel Collection intersect() and intersectByKeys() Method Example — ItSolutionStuff.com (itsolutionstuff.com)
- An Introduction to Laravel Collections — Medium (Medium)

