Как получить доступ к 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