Collection::pluck
Extracts the values of one key from every item, optionally keying the result by another.
public function pluck(\Closure|string|int|array|null $value, \Closure|string|null $key = null): staticParameters
| Parameter | Type | Description |
|---|---|---|
$$value | \Closure|string|int|array|null | The key to read from each item. Strings are split on dots for nested access; a closure receives the item and returns the value. |
$$keyoptional | \Closure|string|null= null | Key to use for each entry in the result. Omit it for a plain, numerically indexed list. |
Return value
Illuminate\Support\CollectionA new collection of the extracted values, keyed by the second argument when one is given.
pluck is column extraction: give it a key and it returns a flat collection of that key's value from every item. It reads through data_get, so it works on arrays, objects and Eloquent models alike, and a second argument lets you key the result by another field instead of getting a plain list.
When to reach for it
Turning a result set into a list of ids for a follow-up whereIn, building id => name pairs for a select box, or reducing rows to a single field before implode, sum or unique. It is shorter and clearer than a map that only reaches for one field.
What trips people up
String keys are always exploded on dots. That is what makes 'venue.city' work, and it also means a literal key containing a dot can never be reached with a string — pass a closure. The * wildcard is supported for descending into nested lists, which returns nested arrays rather than a flat list.
Items missing the key yield null rather than being skipped, so the output always has the same length as the input; filter afterwards if that is not what you want. And when a key argument is supplied, duplicate keys collapse to the last matching row exactly as they do in keyBy.
Example
When to use it
- Collect the ids from a result set to feed a whereIn query.
- Build a value => label array for a select box from loaded models.
- Reduce rows to one numeric column before summing or averaging it.
Frequently asked questions
How do I get a list of ids from a collection of models?
Call $models->pluck('id'), which returns a collection of the id values; add ->all() for a plain array or ->unique()->values() before a whereIn.
Can it read a nested value?
Yes — a string key is split on dots, so 'venue.city' descends into nested arrays and objects, and '*' works as a wildcard for nested lists.
What happens when an item is missing the key?
The entry is null rather than being skipped, so the result always has as many items as the input. Chain filter() if you want the gaps removed.
More examples
Duplicate keys collapse
With a key argument the last matching row wins, so the first dump has just two entries, Tesla => black and Pagani => orange. Without the key argument every value survives as a four-item list.
<?php
$cars = collect([
['brand' => 'Tesla', 'color' => 'red'],
['brand' => 'Pagani', 'color' => 'white'],
['brand' => 'Tesla', 'color' => 'black'],
['brand' => 'Pagani', 'color' => 'orange'],
]);
print_r($cars->pluck('color', 'brand')->all());
print_r($cars->pluck('color')->all());Wildcards and closures
Dot notation returns the nested arrays as they are, so flatten() is needed for a single list of speakers. The last dump shows the closure form, which is the only way to read a key whose name genuinely contains a dot — the string form would look for a nested 'load' inside 'cpu'.
<?php
$events = collect([
['name' => 'Laracon', 'speakers' => ['first_day' => ['Rosa', 'Judith']]],
['name' => 'VueConf', 'speakers' => ['first_day' => ['Abigail', 'Joey']]],
]);
print_r($events->pluck('speakers.first_day')->all());
print_r($events->pluck('speakers.first_day')->flatten()->all());
// A literal key containing a dot needs a closure.
$metrics = collect([
['cpu.load' => 0.4],
['cpu.load' => 0.9],
]);
print_r($metrics->pluck(fn (array $row) => $row['cpu.load'])->all());Ids for a follow-up query
The standard two-query pattern for avoiding an N+1: pluck the foreign keys, load the related rows in one go, then key them for lookup. It needs Eloquent and a database, so it is shown rather than executed.
<?php
$authorIds = $posts->pluck('author_id')->unique()->values();
$authors = User::whereIn('id', $authorIds)->get()->keyBy('id');
foreach ($posts as $post) {
echo $post->title . ' by ' . $authors[$post->author_id]->name . PHP_EOL;
}
Discussion