You can do this using a combination of existing Collection methods. It may be a little hard to follow at first, but it should be easy enough to break down.
// get your main collection with all the attributes...
$users = Users::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map(function ($user) {
return collect($user->toArray())
->only(['id', 'name', 'email'])
->all();
});
Explanation
First, the map() method basically just iterates through the Collection, and passes each item in the Collection to the passed in callback. The value returned from each call of the callback builds the new Collection generated by the map() method.
collect($user->toArray()) is just building a new, temporary Collection out of the Users attributes.
->only(['id', 'name', 'email']) reduces the temporary Collection down to only those attributes specified.
->all() turns the temporary Collection back into a plain array.
Put it all together and you get “For each user in the users collection, return an array of just the id, name, and email attributes.”
Laravel 5.5 update
Laravel 5.5 added an only method on the Model, which basically does the same thing as the collect($user->toArray())->only([...])->all(), so this can be slightly simplified in 5.5+ to:
// get your main collection with all the attributes...
$users = Users::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map(function ($user) {
return $user->only(['id', 'name', 'email']);
});
If you combine this with the “higher order messaging” for collections introduced in Laravel 5.4, it can be simplified even further:
// get your main collection with all the attributes...
$users = Users::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map->only(['id', 'name', 'email']);