Как получить доступ к n-му объекту в объекте коллекции Laravel?

У меня есть объект коллекции laravel.

Я хочу использовать в ней n-ю модель.

Как мне получить доступ к нему?

Edit:

Я не могу найти подходящий метод в документации laravel. Я мог бы итерировать коллекцию в цикле foreach и сломаться, когда найдется n-й элемент:

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

Но это кажется беспорядочным.

Более чистый способ состоял бы в том, чтобы выполнить описанный выше цикл один раз и создать простой массив, содержащий все объекты в коллекции. Но это кажется ненужным дублированием.

В документации класса коллекции laravel существует метод выборки, но я думаю, что это выборку из коллекции, соответствующей первичному ключу, а не n-го в коллекции.

Ответ 1

Увидев, что Illuminate\Support\Collection реализует ArrayAccess, вы должны просто использовать квадратную нотацию, т.е.

$collection[$nth]

Это вызывает offsetGet внутренне, что вы также можете использовать

$collection->offsetGet($nth)

и, наконец, вы можете использовать метод get, который позволяет использовать необязательное значение по умолчанию

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

Ответ 2

@Phil ответ не совсем получает n-й элемент, так как ключи могут быть неупорядочены. Если у вас есть красноречивая коллекция из db-запроса, она будет работать нормально, но если ваши ключи не являются последовательными, вам нужно сделать что-то другое.

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

Вместо этого мы можем сделать $collection->values()[1] // string(4) bash который использует array_values()

Или сделайте макрос для этого:

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

Пример использования макроса:

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

Ответ 3

Если у вас возникли проблемы с сохранением индексов после сортировки... вы можете создать новую коллекцию из значений этой коллекции и попытаться получить доступ к вновь проиндексированной коллекции, как вы ожидаете:

например Получить второй самый дорогой предмет в коллекции

$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

Похоже на ответ морфов, но не то же самое. Простое использование values() после сортировки не даст ожидаемых результатов, поскольку индексы остаются связанными с каждым элементом.

Благодарим @howtomakeaturn за это решение на Laravel Github:https://github.com/laravel/framework/issues/1335