Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

I have implemented the Iterator class in PHP and built the follow mandatory methods as follows

class I implements Iterator
{

    private $a = [];

    function __construct(array $a)
    {
        $this->a = $a;
    }


    function current()
    {
        return current($this->a);
    }


    function next()
    {
        return next($this->a);
    }


    function previous()
    {

    }


    function valid()
    {
        return key($this->a) !== null;
    }


    function rewind()
    {
        return reset($this->a);
    }


    function key()
    {
        return key($this->a);
    }

}

When constructing a loop and calling our Iterator, I have noticed to get the first element is a problem.

Example

$a = ['a','b','c','d'];

$b = ['twelve', 'eleven', 'ten', 'nine'];

$I = new I($a);


foreach($b as $k => $v)
    echo $I->next();

I want the Iterator to output starting from a, but what happens is our Iterator starts by outputting b.

We can get ideal output by writing some code like the following

for($i = 0; $i < count($a); $i++)
{
    if($i == 0)
        echo $i->current();
    else
        echo $i->next();
}

However the above workaround is not efficent and not very clean at all.

Am I implementing this class wrong? Or am I looping/using it wrong?

share|improve this question
2  
I don't see the value that I provides here. Why not just echo $a[$k] in the foreach loop body? –  George Cummins Mar 26 at 12:15

2 Answers 2

You could try a while instead of a for loop.

while($I->valid())
{
  echo $I->current();
  $I->next();
}
share|improve this answer

Hopefully, the example is illustrative, as the functionality already exists in ArrayIterator.

The iterator is being used wrong in the loop. Iterator::next() advances to the next element, so it can never return the 1st element. One approach is to have separate calls to Iterator::current() and Iterator::next(), one to get the value and the other to advance, as in static void's example. Another is to index the 2nd, non-iterated array, as George Cummins suggests in a comment. A 3rd is to use MultipleIterator to simultaneously iterate over each array.

$items = new MultipleIterator();
$items->attachIterator(new ArrayIterator($a));
$items->attachIterator(new ArrayIterator($b));
foreach ($items as $pair) {
    ...
}

If you're targeting PHP 5.5 or later, you can unpack the values using list.

...
foreach ($items as list($ch, $num)) {
    ...
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.