Re: Proposal: Add ReverseArrayIterator and ForwardArrayIterator to SPL
| From: | Nikita Popov | Date: | Wed, 03 Feb 2021 15:49:59 +0000 |
| Subject: | Re: Proposal: Add ReverseArrayIterator and ForwardArrayIterator to SPL | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-113063@lists.php.net to get a copy of this message | ||
On Wed, Feb 3, 2021 at 4:38 PM Levi Morrison <levim@php.net> wrote:
> Hello, everyone!
>
> This proposal adds two new classes to the SPL:
>
> -
Spl\ReverseArrayIterator. It iterates over an array in
> reverse
> order. It does not duplicate the array.
> - Spl\ForwardArrayIterator. It iterates over an array in
> forward
> (normal) order. It does not duplicate the array.
>
> They both implement Countable which returns the count() of the
> array. The [PR][1] has some examples and discusses why I am proposing
> ForwardArrayIterator when there is already
> ArrayIterator, the
> short of which is for performance. There are timing numbers in [one of
> the comments][2].
>
> When it comes time to vote I may merge this into another RFC with
> [CachedIterable by Tyson Andre][3], which I recommend readers
> also
> take a look at. Whether we team up for the RFC vote or not, I wanted
> to get this out there for discussion and review.
>
> [1]: https://github.com/php/php-src/pull/6535
> [2]:
> https://github.com/php/php-src/pull/6535#issuecomment-769179450
> [3]: https://github.com/php/php-src/pull/6655
>
Hey Levi,
I like the general idea of having an "ArrayIterator but sane".
That said, I don't think that the ReverseArrayIterator +
ForwardArrayIterator pair of iterators approaches this problem correctly.
There are plenty of iterators that could be run in reverse, and I think it
would be silly to create two classes for each of them. E.g. if we introduce
an ObjectPropertyIterator, should there be both
ForwardObjectPropertyIterator and ReverseObjectPropertyIterator? I don't
think so.
I think the correct abstraction for bidirectional iterators is to introduce
an interface
// Or "ReversibleIterator"
interface BidrectionalIterator extends Iterator {
public function prev(): void;
public function end(): void;
}
and then a class along the lines of:
class ReverseIterator implements BidirectionalIterator {
public function __construct(private BidirectionalIterator $iter) {}
public function next() { $this->iter->prev(); }
// etc.
}
This would replace "new ReverseArrayIterator($array)" with "new
ReverseIterator(new ArrayIterator($array))", but in a way that is general,
and composes.
Regards,
Nikita