- カテゴリ: collection
- 掲載バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::take - 関連: slice / forPage / takeUntil / takeWhile / skip
- 変更履歴: 特筆すべき変更なし(Laravel 5以降継続)
要点(TL;DR)
- コレクションの先頭(負数なら末尾)から指定件数だけ取り出す
collect([1,2,3,4])->take(2)→[1,2]- 罠:キーは保持/LazyCollectionは負数非対応/大量データはDB側
limit()推奨
概要
takeはコレクションの一部だけを切り出す最短手。ページ冒頭の「おすすめN件」や、ログの先頭数行だけ確認したい時に使います。非破壊で元のコレクションは変更しません。負数を渡すと末尾から取得できます(通常のCollectionのみ)。
構文 / シグネチャ
use Illuminate\Support\Collection;
public function Collection::take(int $limit): static;
// LazyCollection も同名メソッドを提供
// ※ LazyCollection は負数非対応(末尾からは取れない)
- 引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| $limit | int | ✔ | なし | 取得件数。>0で先頭から、<0で末尾から(Collectionのみ)。0は空。 |
- 戻り値:
Collection(/LazyCollection)— 指定件数以内の要素を含む新しいコレクション - 例外/副作用:例外なし。元コレクションは非破壊。キーは保持。
使用例
最小例
<?php
use Illuminate\Support\Collection;
$items = collect([10, 20, 30, 40]);
// 先頭から2件
$top2 = $items->take(2)->all(); // [10, 20]
// 末尾から2件(Collectionのみ)
$last2 = $items->take(-2)->all(); // [30, 40]
// キーは保持される(必要なら values() で再採番)
$keptKeys = collect(['a' => 1, 'b' => 2, 'c' => 3])->take(2); // keys: a,b
$reindexed = $keptKeys->values()->all(); // [1,2]
実務例
<?php
use Illuminate\Support\Facades\File;
// 大きなログを LazyCollection で先頭100行だけ確認
$first100 = File::lines(storage_path('logs/laravel.log'))
->take(100) // LazyCollection は負数不可
->implode("\n");
// Eloquent:上位5件は「クエリビルダ側」で絞るのが基本
// ※ Collection::take ではなく Query\Builder::limit/take を使う
$topUsers = \App\Models\User::orderByDesc('score')
->limit(5) // または ->take(5)
->get(); // DBから5件だけ取得(メモリ効率◎)
よくある落とし穴・注意
- キー保持:
take()はキーを保持。0,1,2…にしたい場合はvalues()を併用。 - LazyCollectionの負数不可:末尾から取りたい場合は通常の
Collectionに変換してからtake(-N)またはslice(-N)を使用。 - 大量データ:大量件数を
Collection::take()で絞ると全件取得後に切り出しになりがち。DBから取る段階でlimit()/take()で絞る。 sliceとの違い:take(N)は「先頭からN件」のエイリアス的用途。任意オフセットならslice($offset, $length)。
代替・関連APIとの比較
slice($offset, $length):任意位置から取り出し。柔軟だが件数以外も考える時に。forPage($page, $perPage):ページング用途に最適。オフセット計算を隠蔽。takeUntil($callback)/takeWhile($callback):条件成立まで/条件が続く間だけ取得。- クエリビルダ
limit()/take():DB段階で絞るため最も効率的。Collection のtake()とは層が違う。
コレクション固有情報(category規定)
- チェーン可:可(
$col->filter(...)->take(5)->map(...)) - 破壊的/非破壊:非破壊
- キー保持:保持(
values()で再採番可能) - LazyCollection対応:対応(ただし負数不可)
- 計算量の目安:
O(k)(取得件数=k)。ただし事前に全件がメモリにある場合はその取得コストに依存。 - 入出力対応表(サンプル)
| 入力 | 式 | 出力 |
|---|---|---|
[1,2,3,4] | take(2) | [1,2] |
[1,2,3,4] | take(-2) | [3,4](Collectionのみ) |
['a'=>1,'b'=>2,'c'=>3] | take(2) | ['a'=>1,'b'=>2](キー保持) |
['a'=>1,'b'=>2,'c'=>3] | take(2)->values() | [1,2](再採番) |
テスト例(Pest)
<?php
use Illuminate\Support\Collection;
it('takes first and last items correctly', function () {
$col = collect([10, 20, 30, 40]);
expect($col->take(2)->all())->toBe([10, 20]);
// 末尾から(Collectionのみ)
expect($col->take(-2)->all())->toBe([30, 40]);
// キー保持
$withKeys = collect(['a'=>1,'b'=>2,'c'=>3])->take(2);
expect($withKeys->keys()->all())->toBe(['a','b']);
// 再採番
expect($withKeys->values()->all())->toBe([1,2]);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
Call to undefined method take | 対象が配列(array)でCollectionではない | collect($array)でラップする、またはarray_sliceを使う |
| 期待どおりに並ばない/キーが0からでない | take()はキー保持 | values()で再採番 |
| 末尾から取りたいが空になる | LazyCollectionに負数を渡している | いったん->collect()してtake(-N)か、slice(-N)を使う |
| メモリ使用量が大きい | 全件を取得後にtake()している | DBクエリ側でlimit()/take()、またはchunk()/cursor()を検討 |
参考リンク
- Laravel Official Docs — Collections: take
https://laravel.com/docs/12.x/collections#method-take - Laravel Official Docs — Collections: slice / forPage / takeWhile / takeUntil
https://laravel.com/docs/12.x/collections - Laravel Official Docs — Lazy Collections
https://laravel.com/docs/12.x/collections#lazy-collections - Source —
Illuminate\Support\Collection::take()(GitHub)
https://github.com/laravel/framework/blob/12.x/src/Illuminate/Support/Collection.php
