- カテゴリ: collection
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::filter - 関連: reject / where / whereNull / map / first
- 変更履歴: 特になし
要点(TL;DR)
- 真偽判定で要素を残すメソッド。コールバックが
trueを返した要素のみ保持 - 例:
collect([1,2,3,4])->filter(fn($v)=>$v%2===0) - 罠:キーは保持される(再採番は
values())。コールバック省略時は 0, ‘0’, ”, null, false, [] 等が除去される
概要
filter はコールバックの判定に通った要素だけを含む新しいコレクションを返します。キーはそのまま保持されるため、配列として扱うときは values() で連番化すると安全です。コールバック未指定では PHP の「真偽値として偽」の値を除去します。
構文 / シグネチャ
/**
* @param callable(TValue, TKey): bool|null $callback
* @return \Illuminate\Support\Collection<TKey, TValue>
*/
public function filter(callable $callback = null);
- 引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
$callback | `callable | null` | いいえ | null |
- 戻り値:
Collection(非破壊。元のコレクションは変更しない。キー保持) - 例外/副作用:特になし(遅延評価ではない
Collectionは即時処理)
使用例
最小例
use Illuminate\Support\Collection;
$even = collect([1, 2, 3, 4])->filter(fn ($v) => $v % 2 === 0);
// => collect([1 => 2, 3 => 4]) ※キー保持
$evenReindexed = $even->values(); // => [2, 4]
実務例(Eloquent コレクションの条件抽出)
use App\Models\Order;
/** @var \Illuminate\Support\Collection<int, App\Models\Order> $orders */
$orders = Order::with('items')->get();
$needAttention = $orders->filter(function ($order) {
// 期限切れ or 合計金額が一定以上 & 未払い
return ($order->due_date->isPast() || $order->total >= 10000) && ! $order->paid;
});
// 表示用に連番キーへ
$viewData = $needAttention->values();
よくある落とし穴・注意
- キー保持:
filter()はキーを保持。配列として JSON などに渡すなら->values()を併用 - コールバック省略の挙動:
0,'0','',false,null,[]も除去される(意図せず消える場合がある) whereとの違い:whereはプロパティ一致(=)に特化、filterは任意ロジックで柔軟- 性能:時間計算量は O(n)。重いロジックは事前計算や
map→filterの順序最適化を検討 - LazyCollection:
LazyCollectionにも同名メソッドあり(遅延評価)。巨大データでは Lazy の活用が有効
代替・関連APIとの比較
- reject:
filterの逆。残す条件を考えるより除外条件が明確なときに有効 - where / whereStrict:キーや属性の一致で絞り込み(高速・簡潔)。複雑条件なら
filter - first:最初に一致した1件だけ欲しい場合は
filterではなくfirst(fn()=>...) - partition:真偽で通過/不通過を同時に受け取りたい場合に便利(
[$pass, $fail])
入出力対応表(小さなサンプル)
| 入力 | コールバック | 出力 |
|---|---|---|
[1,2,3,4] | v%2===0 | [1=>2, 3=>4](キー保持) |
['a'=>1,'b'=>0,'c'=>2] | null | ['a'=>1,'c'=>2](0 は除去) |
[['s'=>10],['s'=>5]] | $v['s']>=6 | [0=>['s'=>10]] |
テスト例(Pest)
use Illuminate\Support\Collection;
it('filters and keeps keys', function () {
$c = collect([10, 11, 12, 13])->filter(fn($v) => $v % 2 === 0);
expect($c->keys()->all())->toBe([0, 2]) // 元キー保持
->and($c->values()->all())->toBe([10, 12]); // 再採番
});
it('removes falsy when callback omitted', function () {
$c = collect([0, '0', '', null, false, [], 'ok'])->filter();
expect($c->all())->toBe(['ok']); // 偽相当値は除去
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
意図せず '0' や 0 が消えた | コールバック省略で偽相当値が除去 | 明示コールバックで条件を定義する:filter(fn($v)=>$v !== null) など |
| 配列が連番でない | キー保持仕様 | ->values() で再採番 |
| 件数が合わない | 条件が厳しすぎる/型比較の誤り | デバッグ出力や dump()、whereStrict/== の違いを確認 |
| 遅い | 重い処理をコールバック内で毎回実行 | 事前計算・キャッシュ・map での変換後に filter |
参考リンク
- Laravel 公式コレクション:filter(Laravel 12) — https://laravel.com/docs/12.x/collections#method-filter
- Laravel 公式コレクション:reject — https://laravel.com/docs/12.x/collections#method-reject
- Laravel 公式コレクション:where / whereStrict — https://laravel.com/docs/12.x/collections#method-where
- PHP 公式:array_filter — https://www.php.net/array_filter
- Laravel 公式:LazyCollection — https://laravel.com/docs/12.x/collections#lazy-collections

