I have a collection of objects. Every time when I get an element of this collection, I want to be sure that I get next element in this collections, when I get to the end of collection I just simply start to iterate it from very beginning.
For instance:
$listOfObjects = new WrappedCollection(array('Apple','Banana','Pikachu'));
$listOfObjects.getElement(); //I get Apple
$listOfObjects.getElement(); //I get Banana
$listOfObjects.getElement(); //I get Pikachu
$listOfObjects.getElement(); //I get Apple
I already implemented this with SplDoublyLinkedList, but everytime when I need to loop this list, I need to save the position of iterator, I am sure that there is a way to implement this more beautiful.
$this->listOfRunningCampaigns = new \SplDoublyLinkedList();
// Getting element of collection
public function getNextRunningCampaign(): Campaign
{
$this->listOfRunningCampaigns->next();
if ($this->listOfRunningCampaigns->current() !== null)
{
return $this->listOfRunningCampaigns->current();
}
$this->listOfRunningCampaigns->rewind();
return $this->listOfRunningCampaigns->current();
}
Here is example of what I have to do when I loop through collection:
// Saving current iterator position
$currentIteratorPosition = $this->listOfRunningCampaigns->key();
for ($this->listOfRunningCampaigns->rewind(); $this->listOfRunningCampaigns->valid(); $this->listOfRunningCampaigns->next())
{
//... some action
}
$this->moveRunningCampaignsListIterator($currentIteratorPosition);
// Function that moves iterator
private function moveRunningCampaignsListIterator($index): void
{
for ($this->listOfRunningCampaigns->rewind(); $this->listOfRunningCampaigns->valid(); $this->listOfRunningCampaigns->next())
{
if ($this->listOfRunningCampaigns->key() === $index)
{
break;
}
}
}
In my opinion the way I implemented this looks really bad, In near future I am about to make a lot of different actions with the elements of this collection and taking care of iterator every time is not the way I want to see this working. Can you please suggest some ways of implementing this?
Why you don't just use next()
? This built-in function will do the rest with the array pointer for you.
In case you want to develop an array wrapper, I think you should take a look at Doctrine\Common\Collections\ArrayCollection
, or use it directly, they did a great job and it also is available via Composer