PHP: Как создать оболочку для коллекции, которая будет возвращать следующий элемент коллекции при каждом вызове - PullRequest
0 голосов
/ 18 января 2019

У меня есть коллекция предметов. Каждый раз, когда я получаю элемент этой коллекции, я хочу быть уверен, что получу следующий элемент в этих коллекциях, когда я добираюсь до конца коллекции, я просто начинаю повторять его с самого начала.

Например:

    $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

Я уже реализовал это с помощью SplDoublyLinkedList, но каждый раз, когда мне нужно зациклить этот список, мне нужно сохранять позицию итератора, я уверен, что есть способ реализовать это более красиво.

    $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();
    }

Вот пример того, что мне нужно делать, когда я перебираю коллекцию:

    // 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;
            }
        }
    }

По-моему, то, как я это реализовал, выглядит очень плохо. В ближайшем будущем я собираюсь сделать много разных действий с элементами этой коллекции, и каждый раз заботиться об итераторе - это не то, что я хочу видеть за работой. Не могли бы вы предложить несколько способов реализации этого?

1 Ответ

0 голосов
/ 18 января 2019

Почему вы просто не используете next()? Эта встроенная функция сделает все остальное с указателем массива за вас.

Если вы хотите разработать оболочку для массива, я думаю, вам стоит взглянуть на Doctrine\Common\Collections\ArrayCollection или использовать его напрямую, они отлично поработали, и он также доступен через Composer

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...