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

Я думаю, что я нарушаю все правила, преднамеренно создавая повторяющийся вопрос...

другой вопрос имеет принятый ответ. Это, очевидно, решило проблему адеристов, но она не отвечала на титульный вопрос.

Пусть начнется с начала - метод first() реализуется примерно так:

foreach ($collection as $item)
    return $item;

Это, очевидно, более устойчиво, чем принятие $collection[0] или использование других предложенных методов.

Не может быть элемента с индексом 0 или index 15, даже если в коллекции есть 20 элементов. Чтобы проиллюстрировать проблему, откройте эту коллекцию из документов:

$collection = collect([
    ['product_id' => 'prod-100', 'name' => 'desk'],
    ['product_id' => 'prod-200', 'name' => 'chair'],
]);

$keyed = $collection->keyBy('product_id');

Теперь у нас есть какой-нибудь надежный (и, желательно, сжатый) способ доступа к n-му элементу $keyed?

Мое собственное предложение было бы сделать:

$nth = $keyed->take($n)->last();

Но это будет давать неправильный элемент ($keyed->last()) всякий раз, когда $n > $keyed->count(). Как мы можем получить n-й элемент, если он существует, и null, если он не просто работает first()?

Изменить

Чтобы прояснить, рассмотрим эту коллекцию:

$col = collect([
    2 => 'a',
    5 => 'b',
    6 => 'c',
    7 => 'd']);

Первый элемент $col->first(). Как получить второй?

$col->nth(3) должен возвращать 'c' (или 'c', если он основан на 0, но это будет несовместимо с first()). $col[3] не будет работать, он просто вернет ошибку.

$col->nth(7) должен возвращать null, потому что нет седьмого элемента, их всего четыре. $col[7] не будет работать, он просто вернет 'd'.

Вы можете перефразировать вопрос как "Как получить n-й элемент в заказе foreach?" если это более понятно для некоторых.

Ответ 1

Я думаю, что быстрее и эффективнее использовать память slice() метод:

$collection->slice($n, 1);

Ответ 2

Вы можете попробовать это с помощью функции values() как:

$collection->values()->get($n);

Ответ 3

Основываясь на ответе Алексея, вы можете создать макрос в AppServiceProvider (добавить его внутри метода register):

use Illuminate\Support\Collection;

Collection::macro('getNth', function ($n) {
   return $this->slice($n, 1)->first();
});

и затем вы можете использовать это в своем приложении:

$collection = ['apple', 'orange'];

$collection->getNth(0) // returns 'apple'
$collection->getNth(1) // returns 'orange'
$collection->getNth(2) // returns null
$collection->getNth(3) // returns null

Ответ 4

Может быть, не самый лучший вариант, но вы можете получить элемент из массива внутри коллекции

$collection->all()[0]