Collections - how to get concrete element index/position in collection?

Hi, I would like to use Collections to code following feature:

Let’s assume I have collection of Document entities. Each Document entity has id and release_date field. In some cases I need to find previous and next document in relation to the current, selected document. It is easy to code it with foreach loops, like here:

$allDocuments = [/*collection of documents*/];

$found = false;
$index = 0;
foreach ($allDocuments as $document) {
    if ($currentDocument->id == $document->id) {
        $found = true;
        break;
    }

    $index++;
}

$currentDocumentIndex = ($found) ? $index : false;

// And this is how I can get now next and prev document:

if (isset($allDocuments[$currentDocumentIndex - 1])) {
$this->set('newerDocument', $allDocuments[$currentDocumentIndex - 1]);
}

if (isset($allDocuments[$currentDocumentIndex + 1])) {
$this->set('olderDocument', $allDocuments[$currentDocumentIndex + 1]);
}

As you can see it is a lot of code. I would like to simplify it by using Collections. Is it possible?

I probably should use $c->take(1, $currentPdfDocumentIndex +/- 1) but I do not how to find $currentDocumentIndex in collection. It would be cool if I can use just: $prevDoc = $c->prev() and $nextDoc = $c->next(); instead of take, but I am not sure if it is possible.

Well, there’s a lot of ways to do what you want, but i suggest this:

$allDocuments = $collection->toList(); // converts the collection to array
$index = array_search($currentDocument->id, array_column($allDocuments, 'id')); // returns false if id not exists

if ($key !== false) {
  // And this is how I can get now next and prev document:
  if (isset($allDocuments[$index - 1])) {
    $this->set('newerDocument', $allDocuments[$index - 1]);
  }
  if (isset($allDocuments[$index + 1])) {
    $this->set('olderDocument', $allDocuments[$index + 1]);
  }
}

I think this will not work because array_column can not work with array of objects (in PHP < 7). Documents are Entities.

Assuming $allDocuments is a ResultSet, you can call $allDocuments->hydrate(false);