take — 先頭(または末尾)から指定件数を取り出す

  • カテゴリ: 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 は負数非対応(末尾からは取れない)
  • 引数(表)
引数必須既定値説明
$limitintなし取得件数。>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()を検討

参考リンク

レン (Wren)

こんにちは。レンです。

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

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

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

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

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

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