Citizen
Citizen

Reputation: 12947

How do I get the next item in a Laravel collection?

Let's say I have a child of a parent collection and I want to know who the next sibling is. My parent collection is ordered differently than internal id so I can't use the method described here:

Laravel previous and next records

Which would work except I'm sorting by name and time, not internal id. I'm hoping that there's a way to just get the parent collection, find this child's position within it, and then look forward or back within that collection to get next or previous.

Edit:

So, I made this, which works, but seems clunky. Is there a more efficient way to do this?

public function next()
{
    $previous = null;
    foreach ($this->album->media as $media)
    {
        if(!empty($previous && $previous->id == $this->id))
        {
            // Yay! Our current record  is the 'next' record.
            return $media->id;
        }
        $previous = $media;
    }
    return null;
}

public function previous()
{
    $previous = null;
    foreach ($this->album->media as $media)
    {
        if(!empty($previous && $media->id == $this->id))
        {
            // Yay! Our previous record is the 'previous' record.
            return $previous;
        }
        $previous = $media->id;
    }
    return null;
}

Upvotes: 1

Views: 7840

Answers (3)

Pri Nce
Pri Nce

Reputation: 711

Here is the simple line of code

// next
function next($product_id)
{
  $next = Product::where('id', '>', $product_id)->first();
  return $next;
}

// previous
function previous($product_id)
{
  $previous = Product::where('id', '<', $product_id)->first();
  return $previous;
}

Upvotes: 2

Leo Silver
Leo Silver

Reputation: 51

You should never load the entire table to loop through it to find the next/previous item, instead do it this way:

$next = $this->album->media()->orderBy('id')->where('id', '>', $this->id)->first();

Upvotes: 3

Citizen
Citizen

Reputation: 12947

This did the trick:

public function next()
{
    $previous = null;
    foreach ($this->album->media as $media)
    {
        if(!empty($previous && $previous->id == $this->id))
        {
            // Yay! Our current record  is the 'next' record.
            return $media->id;
        }
        $previous = $media;
    }
    return null;
}

public function previous()
{
    $previous = null;
    foreach ($this->album->media as $media)
    {
        if(!empty($previous && $media->id == $this->id))
        {
            // Yay! Our previous record is the 'previous' record.
            return $previous;
        }
        $previous = $media->id;
    }
    return null;
}

Upvotes: 0

Related Questions