install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/riasvdv/skills/laravel-collections" ~/.claude/skills/comeonoliver-skillshub-laravel-collections && rm -rf "$T"
manifest:
skills/riasvdv/skills/laravel-collections/SKILL.mdsource content
Laravel Collections
Quick Decision Guide
"Which method do I use?"
Find items:
| Need | Method |
|---|---|
| First item matching condition | or |
| First item or throw | |
| Exactly one match or throw | |
| Check value exists | or |
| Check key exists | |
| All items match condition | |
Transform items:
| Need | Method |
|---|---|
| Transform each item | |
| Transform + flatten one level | |
| Extract one field | |
| Extract field, keyed by another | |
| Select multiple fields | |
| Change keys | or |
| Map into class instances | |
Filter items:
| Need | Method |
|---|---|
| Keep matching items | |
| Remove matching items | |
| Filter by field value | |
| Filter by field in list | |
| Keep specific keys only | |
| Remove specific keys | |
| Remove duplicates | |
Group & organize:
| Need | Method |
|---|---|
| Group by field | |
| Group with custom key+value | |
| Split pass/fail | |
| Key by field (1 item per key) | |
| Split into chunks | |
Aggregate:
| Need | Method |
|---|---|
| Sum values | |
| Average | |
| Min/Max | / |
| Reduce to single value | |
| Count occurrences | |
| Percentage matching | |
Combine collections:
| Need | Method |
|---|---|
| Merge (overwrites string keys) | |
| Append values (re-indexes) | |
| Keep only shared values | |
| Get values not in other | |
| Pair items by index | |
Mutability Rules
Immutable (return new collection) - almost everything:
map, filter, reject, sort, merge, pluck, unique, ...
Mutating (modify in place, return
$this) - memorize these:
transform, push, prepend, put, pull, pop, shift, splice, forget
// WRONG mental model: $filtered = $collection->push('item'); // $collection IS modified // Correct approach when you want immutability: $new = $collection->concat(['item']); // $collection is unchanged
Common Pitfalls
1. each()
vs map()
vs transform()
each()map()transform()// each(): Side-effects, returns ORIGINAL collection $users->each(fn($u) => $u->notify(new Welcome)); // map(): Transformation, returns NEW collection (original unchanged) $names = $users->map(fn($u) => $u->name); // transform(): Transformation, MUTATES original collection $users->transform(fn($u) => $u->name); // $users is now a collection of names!
2. pluck()
key overwrites
pluck()When using
pluck('name', 'id'), duplicate keys silently overwrite:
collect([ ['id' => 1, 'name' => 'Alice'], ['id' => 1, 'name' => 'Bob'], // Overwrites Alice ])->pluck('name', 'id'); // [1 => 'Bob'] -- Alice is lost!
Use
groupBy if duplicates are expected.
3. filter()
without callback removes all falsy values
filter()collect([0, 1, '', 'hello', null, false, []])->filter()->all(); // [1, 'hello'] -- 0, '', null, false, [] are ALL removed
Use
whereNotNull() if you only want to remove nulls.
4. N+1 queries with collection iteration
// BAD: N+1 queries $users->each(fn($user) => $user->posts->count()); // GOOD: Eager load first $users->load('posts'); $users->each(fn($user) => $user->posts->count());
5. Memory with large datasets
// BAD: Loads all users into memory User::all()->each(fn($u) => process($u)); // GOOD: Constant memory with cursor User::cursor()->each(fn($u) => process($u)); // GOOD: Chunked processing User::chunk(1000, fn($users) => $users->each(fn($u) => process($u)));
6. sort()
preserves keys
sort()collect([3, 1, 2])->sort()->all(); // [1 => 1, 2 => 2, 0 => 3] -- keys preserved! collect([3, 1, 2])->sort()->values()->all(); // [1, 2, 3] -- use values() to re-index
Higher-Order Messages
Proxy pattern for clean, concise collection operations:
// Instead of: $users->map(function ($user) { return $user->name; }); // Write: $users->map->name; // Works with methods too: $users->each->markAsVip(); $users->sum->votes; $users->filter->isAdmin(); $users->sortBy->name; $users->reject->isBlocked(); $users->groupBy->department;
Supported on:
average, avg, contains, each, every, filter, first, flatMap,
groupBy, keyBy, map, max, min, partition, reject, skipUntil, skipWhile,
some, sortBy, sortByDesc, sum, takeUntil, takeWhile, unique.
Extending with Macros
Register custom collection methods (typically in a service provider's
boot method):
use Illuminate\Support\Collection; Collection::macro('toUpper', function () { return $this->map(fn($value) => strtoupper($value)); }); // Usage collect(['foo', 'bar'])->toUpper(); // ['FOO', 'BAR']
Reference Files
- Full method reference: See references/methods.md for every Collection method with signatures and descriptions
- LazyCollection: See references/lazy-collections.md for LazyCollection-specific methods, usage patterns, and when to choose lazy vs eager