Laravel Tips集 ~Collectionの便利技大全~
Laravel Collections Tips チートシート
各セクションでは、Laravel のコレクション操作に関する便利なメソッドと使い方をまとめています。
1. containsOneItem メソッド
コレクションが1つの要素のみを持つかどうか、count() を使う代わりに直感的にチェックできます。
<?php
// 従来の書き方
collect([1])->count() === 1;
// 新しい書き方
collect([1])->containsOneItem(); // true
collect([])->containsOneItem(); // false
collect([1, 2])->containsOneItem(); // false
2. dot と undot メソッド
多次元のコレクションを、1次元にフラット化(dot)したり、逆に元の多次元構造に戻す(undot)ことができます。
$collection = collect(['products' => ['desk' => ['price' => 100]]]);
$dotted = $collection->dot(); // ['products.desk.price' => 100]
$undotted = $collection->undot(); // ['products' => ['desk' => ['price' => 100]]]
3. times メソッド
指定回数分だけコレクションを生成する際に、times() メソッドでクロージャを N 回実行して値を返すコレクションを作成できます。
$collection = Collection::times(10, function (int $number) {
return $number * 9;
});
$collection->all();
// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
4. コレクションの要素の型チェック(ensure メソッド)
コレクション内の各要素が指定した型であることを確認し、そうでなければ例外を投げることができます。
<?php
// 従来の書き方
return $collection->each(function ($item) {
if (!$item instanceof User) {
throw new UnexpectedValueException('😕');
}
});
// 簡潔な書き方
return $collection->ensure(User::class);
// 複数の型を許可(OR 条件)
return $collection->ensure([User::class, Customer::class]);
// プリミティブ型の場合
return $collection->ensure('int');
5. every メソッド
コレクションのすべての要素が、指定した条件を満たしているかをチェックします。空のコレクションの場合は true を返します。
<?php
$result = collect([1, 2, 3])->every(fn (int $value, int $key) => $value > 2);
// $result は false
$result = collect([])->every(fn (int $value, int $key) => $value > 2);
// 空の場合は true
6. forget メソッド
キーを指定して、コレクションから要素を削除できます。
<?php
$collection = collect(['name' => 'John Doe', 'framework' => 'laravel']);
$collection->forget('name');
$collection->all(); // ['framework' => 'laravel']
7. skipUntil メソッド
指定した条件を満たすまで、コレクション内の要素をスキップして残りの部分を取得できます。
<?php
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(function (int $item) {
return $item >= 3;
});
$subset->all(); // [3, 4]
8. zip メソッド
複数のコレクションを、インデックスごとに組み合わせて新しいコレクションを作成します。
<?php
$collection = collect(['Chair', 'Desk']);
// それぞれのインデックスごとに結合する
$zipped = $collection->zip([100, 200]);
$zipped->all(); // [['Chair', 100], ['Desk', 200]]
9. whenNotEmpty メソッド
コレクションが空でない場合に、指定したクロージャ内の処理を実行します。
<?php
$collection = collect(['michael', 'tom']);
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('adam');
});
$collection->all(); // ['michael', 'tom', 'adam']
$collection = collect(); // 空のコレクション
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('adam');
});
$collection->all(); // []
10. search メソッド
コレクション内で、値または条件に一致する最初の要素のキーを検索します。
<?php
$collection = collect([2, 4, 6, 8]);
$collection->search('4'); // 1(インデックス)
$collection->search('4', strict: true); // false(厳密検索で見つからない)
$collection->search(fn (int $item, int $key) => $item > 5); // 2(インデックス)
11. sole メソッド
条件に一致する要素がただ1つであることを保証し、唯一の要素を取得します。複数見つかった場合は例外が投げられます。
<?php
// 2 が唯一の要素として返される
collect([1, 2, 3, 4])->sole(fn (int $value, int $key) => $value === 2);
// 複数見つかった場合は例外発生
collect([1, 2, 2, 4])->sole(fn (int $value, int $key) => $value === 2);
12. 偽値のフィルタリング
filter() にコールバックを渡さない場合、false、null、空文字、0、空配列などの偽値が自動的に除外されます。
<?php
$collection = collect([1, 2, 3, null, false, '', 0, []]);
$collection->filter()->all(); // [1, 2, 3]
13. join メソッド(より良い implode)
join() は implode と同様に文字列を連結しますが、最後のセパレーターを別途指定できるため、自然な文章表現が可能です。
<?php
collect(['a', 'b', 'c'])->join(', ', ''); // 'a, b, c'
collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'
collect(['a'])->join(', ', ', and '); // 'a'
collect([])->join(', ', ', and '); // ''
14. 高階メッセージ(Higher Order Messages)
コレクションの各要素に対して、メソッドを直接呼び出す簡潔な記法です。たとえば、各要素に対して同じメソッドを呼ぶ場合などに便利です。
<?php
use App\Models\User;
$users = User::where('votes', '>', 500)->get();
// 通常の書き方
$users->each(fn(User $user) => $user->markAsVip());
// 高階メッセージを利用すると、以下のように記述可能
$users->each->markAsVip();
15. modelKeys メソッド
pluck() の代わりに modelKeys() を使うことで、モデルの主キーをより明示的に取得できます。主キー名が変更されても自動的に対応してくれます。
<?php
use App\Models\User;
// 従来の書き方
$ids = User::all()->pluck('id');
// 新しい書き方
$ids = User::all()->modelKeys();
16. pipe メソッド
pipe() を使うと、コレクションを指定したクロージャに渡し、その結果を返すことができます。複雑な変換処理をシンプルに記述可能です。
<?php
use Illuminate\Support\Collection;
$collection = collect([1, 2, 3]);
$collection->pipe(fn (Collection $collection) => $collection->sum()); // 6
$collection->pipe(fn (Collection $collection) => ['numbers' => $collection->toArray()]);
// 結果: ['numbers' => [1, 2, 3]]
17. duplicates メソッド
コレクション内の重複した値を検出できます。緩やかな比較と、厳密な比較を行うメソッドが用意されています。
<?php
$collection = collect(['a', 'b', 'a', 'c', 'b', 100, '100']);
// 緩やかな比較(型の違いは無視)
$collection->duplicates(); // ['a', 'b', '100']
// 厳密な比較(型も考慮)
$collection->duplicatesStrict(); // ['a', 'b']
元記事
Discussion