Collection::skip

Drops the given number of items from the front of a collection and returns the rest.

Signature
Collection::skip(int $count): static

Parameters

ParameterTypeDescription
$$countintHow many items to drop from the beginning of the collection.

Return value

staticA new collection with the first $count items removed. Keys are preserved.

Internally this is just slice($count), which has one consequence the documentation's example hides: keys are preserved. Skipping four items from a ten-item list leaves keys 4 through 9, not 0 through 5. The printed values look right, so the bug surfaces later — in json_encode(), which emits an object, or in code that reads [0] and gets nothing. Chain values() when the result leaves your own code.

Reach for it for offsets you already know: dropping a CSV header row, skipping a leading sentinel, or paging an in-memory array with skip($page * $perPage)->take($perPage). For database results, an offset in the query is nearly always better than fetching everything and skipping in PHP.

Skipping by condition

When the number of items to drop is not known up front, the siblings do the work: skipWhile($cb) drops items while the callback is true and returns everything from the first false onward, and skipUntil($cb) — which also accepts a plain value — drops until the callback is true. Both return an empty collection if their condition is never satisfied, which is a common surprise.

Skipping more items than exist returns an empty collection rather than an error.

Example

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

When to use it

  • Drop the header row from a parsed CSV before mapping the data rows.
  • Page through an already-loaded collection with skip($offset)->take($perPage).
  • Ignore a fixed number of warm-up samples before averaging a benchmark run.

Frequently asked questions

Why does skip leave my array starting at key 4?

Because skip() is implemented as slice() and preserves the original keys. Chain values() to reindex from zero, which matters as soon as you json_encode the result or index into it.

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

You get an empty collection, not an error or a negative offset. Check isEmpty() if an empty result needs different handling.

How do I skip items until a condition is met?

Use skipUntil() to drop items until the callback returns true, or skipWhile() to drop them while it returns true. Both return an empty collection if the condition is never satisfied.

More examples

Skipping by condition instead of by count

The three print_r calls give [12, 18, 4], [18, 4] and [12, 18, 4]. The final dump is array(0) {} — when the skipWhile callback never returns false, every item is skipped and you get an empty collection rather than the original.

Example · php
<?php

$readings = collect([0, 0, 0, 12, 18, 4]);

// Drop leading zeroes: skip WHILE the callback is true.
print_r($readings->skipWhile(fn (int $n) => $n === 0)->values()->all());

// Drop everything before the first big reading: skip UNTIL true.
print_r($readings->skipUntil(fn (int $n) => $n > 15)->values()->all());

// skipUntil also takes a plain value.
print_r($readings->skipUntil(12)->values()->all());

// The condition is never met, so nothing survives.
var_dump($readings->skipWhile(fn (int $n) => $n < 100)->all());

Paging an in-memory collection

Prints pages of 1-10, 11-20 and 21-25 — the last page is short rather than an error. take() after skip() is the in-memory equivalent of SQL's OFFSET/LIMIT, and implode() sidesteps the preserved keys entirely.

Example · php
<?php

$rows = collect(range(1, 25));

$perPage = 10;

foreach ([1, 2, 3] as $page) {
    $slice = $rows->skip(($page - 1) * $perPage)->take($perPage);

    echo "page {$page}: " . $slice->implode(',') . PHP_EOL;
}

In an application: dropping a CSV header

skip(1) removes the header row after it has been read for the column names. values() is chained before map() so the imported rows are numbered from zero — without it the first data row would sit at key 1 and any later chunking by index would be off by one.

Example · php
<?php

namespace App\Imports;

use Illuminate\Support\Collection;

class ProductImporter
{
    public function parse(Collection $lines): Collection
    {
        $header = str_getcsv($lines->first());

        return $lines
            ->skip(1)
            ->values()
            ->map(fn (string $line) => array_combine($header, str_getcsv($line)));
    }
}

Discussion

  • Be the first to comment on this lesson.