Collection::take

Returns a new collection of the first n items, or the last n when the count is negative.

Signature
public function take(int $limit): static

Parameters

ParameterTypeDescription
$limitintHow many items to take. A positive value takes from the start, a negative value takes that many from the end, and 0 returns an empty collection.

Return value

staticA new collection containing at most $limit items, with the original keys preserved.

take is a thin wrapper over slice: a positive limit becomes slice(0, $limit) and a negative one becomes slice($limit, abs($limit)). It never mutates the receiver and never errors on an over-long limit — asking for 99 items from a collection of 6 simply returns all 6.

When to reach for it

Any "top N" or "latest N" shortlist, usually right after a sort: ->sortByDesc('score')->take(10). The negative form is the compact way to grab a tail — the last three log lines, the final page of a chunked list — without computing an offset yourself.

What trips people up

Keys are preserved, because slice passes true for array_slice's preserve_keys. For take(3) on a list that is invisible, since the keys are already 0, 1, 2. For take(-2) it is very visible: you get keys 4 and 5, and the collection will then JSON-encode as an object like {"4":...,"5":...} rather than an array. Chain values() whenever the result crosses into JSON or a numerically indexed API response.

Also note take counts items, not a condition. To stop at the first item that fails a test, use takeWhile.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Show the ten highest-scoring rows after a sortByDesc
  • Grab the last three entries of a log without computing an offset
  • Cap an unbounded import batch at a safe number of rows per run
  • Build a preview list of the first few items with a "show all" link

Frequently asked questions

How do I get the last N items of a Laravel collection?

Pass a negative number: $collection->take(-3) returns the final three items. The original keys come back with them, so add ->values() if you need a zero-indexed result.

What happens if I take more items than the collection has?

You get the whole collection back with no error, because take() delegates to array_slice, which stops at the end of the array. take(0) returns an empty collection.

Why does my take() result JSON-encode as an object instead of an array?

Because take() preserves the original keys and a non-sequential key set encodes as a JSON object. Chain ->values() before toJson() to reindex from zero.

More examples

Top N after sorting, ready for JSON

This is the single most common take() bug in an API controller. sortByDesc preserves keys and take preserves them too, so the two-item result still carries keys 1 and 2 and json_encode emits an object. The values() call is what makes the front end receive an array.

Example · php
<?php

$players = collect([
    ['name' => 'Ada',   'score' => 71],
    ['name' => 'Grace', 'score' => 96],
    ['name' => 'Alan',  'score' => 88],
    ['name' => 'Edsger','score' => 62],
]);

$top = $players->sortByDesc('score')->take(2);

// sortByDesc kept the original keys, and so did take.
echo $top->toJson(), "\n";

// values() reindexes so it encodes as a JSON array.
echo $top->values()->toJson(), "\n";

// Output:
// {"1":{"name":"Grace","score":96},"2":{"name":"Alan","score":88}}
// [{"name":"Grace","score":96},{"name":"Alan","score":88}]

take() versus slice() and skip()

take(3) is exactly slice(0, 3). When you need a window that does not start at either end, slice is the direct tool; skip()->take() expresses the same window in offset/limit terms, which reads better when the numbers come from pagination parameters.

Example · php
<?php

$letters = collect(['a', 'b', 'c', 'd', 'e', 'f', 'g']);

// take is slice from a fixed offset.
print_r($letters->take(3)->values()->all());

// slice picks an arbitrary window.
print_r($letters->slice(2, 3)->values()->all());

// skip + take is manual pagination.
print_r($letters->skip(3)->take(2)->values()->all());

// Output:
// Array ( [0] => a [1] => b [2] => c )
// Array ( [0] => c [1] => d [2] => e )
// Array ( [0] => d [1] => e )

Discussion

  • Be the first to comment on this lesson.