theHands
theHands

Reputation: 423

How to access the nth object in a Laravel collection object?

I have a laravel collection object.

I want to use the nth model within it.

How do I access it?

Edit:

I cannot find a suitable method in the laravel documentation. I could iterate the collection in a foreach loop and break when the nth item is found:

foreach($collection as $key => $object)
{
    if($key == $nth) {break;}
}
// $object is now the nth one

But this seems messy.

A cleaner way would be to perform the above loop once and create a simple array containing all the objects in the collection. But this seems like unnecessary duplication.

In the laravel collection class documentation, there is a fetch method but I think this fetches an object from the collection matching a primary key, rather than the nth one in the collection.

Upvotes: 32

Views: 38079

Answers (4)

Lew  Perren
Lew Perren

Reputation: 1239

I am late to this question, but I thought this might be a useful solution for someone.

Collections have the slice method with the following parameters:

 $items->slice(whereToStartSlice, sizeOfSlice);

Therefore, if you set the whereToStartSlice parameter at the nth item and the sizeOfSlice to 1 you retrieve the nth item.

Example:

 $nthItem = $items->slice($nth,1);

Upvotes: 8

Noah Gary
Noah Gary

Reputation: 960

If you are having problems with the collection keeping the indices after sorting... you can make a new collection out of the values of that collection and try accessing the newly indexed collection like you would expect:

e.g. Get the second highest priced item in a collection

$items = collect(
                 [
                  "1" => ["name" => "baseball", "price" => 5],
                  "2" => ["name"=> "bat", "price" => 15],
                  "3" => ["name" => "glove", "price" => 10]
                 ]
                );

collect($items->sortByDesc("price")->values())[1]["name"];

// Result: glove

Similar to morphs answer but not the same. Simply using values() after a sort will not give you the expected results because the indices remain coupled to each item.

Credit to @howtomakeaturn for this solution on the Laravel Github: https://github.com/laravel/framework/issues/1335

Upvotes: 2

Harry
Harry

Reputation: 2526

@Phil's answer doesn't quite obtain the nth element, since the keys may be unordered. If you've got an eloquent collection from a db query it'll work fine, but if your keys aren't sequential then you'll need to do something different.

$collection = collect([0 => 'bish', 2 => 'bash']); $collection[1] // Undefined index

Instead we can do $collection->values()[1] // string(4) bash which uses array_values()

Or even make a macro to do this:

Collection::macro('nthElement', function($offset, $default = null) {
    return $this->values()->get($offset, $default);
}):

Example macro usage:

$collection = collect([0 => 'bish', 2 => 'bash']);
$collection->nthElement(1) // string(4) 'bash'
$collection->nthElement(3) // undefined index
$collection->nthElement(3, 'bosh') // string (4) bosh

Upvotes: 15

Phil
Phil

Reputation: 164832

Seeing as Illuminate\Support\Collection implements ArrayAccess, you should be able to simply use square-bracket notation, ie

$collection[$nth]

This calls offsetGet internally which you can also use

$collection->offsetGet($nth)

and finally, you can use the get method which allows for an optional default value

$collection->get($nth)
// or
$collection->get($nth, 'some default value')

Upvotes: 62

Related Questions