On 18 August 2026 16:08:58 BST, "Rowan Tommins [IMSoP]" <[email protected]> 
wrote:
>In fact, the simplest starting point would be no functions at all, just an 
>optimised ArraySliceIterator. The actual search part is fairly easy to write 
>in user code.
>
>Then in a separate RFC, add a new set of functions like "iter_search", 
>"iter_any", etc, which would be useful with *any* iterator, not just this 
>specific one.


Just to add, both ArraySliceIterator and iter_search can be implemented in less 
than twenty lines of code each: <https://3v4l.org/HmYZV>

Which is great for adding them natively: users of older versions or who need to 
support multiple versions can "polyfill" them to start using straight away, and 
then get more optimised versions when they upgrade.

To be fair, the same is true of array_search_range: a memory-efficient user 
implementation is simple, but can't be quite as time-efficient as an internal 
one because it can't use optimisations based on the memory layout of the array. 
Only lightly tested, but covers all of the proposed signature in about 30 
lines: <https://3v4l.org/VAsXY>

For the archive, here's the sample implementations: 

```
class ArraySliceIterator implements IteratorAggregate {
        private LimitIterator $backingIterator;

        public function __construct(array $array, int $offset, int $limit) {
                $this->backingIterator = new LimitIterator(
                        new ArrayIterator($array),
                        $offset,
                        $limit
                );
        }

        public function getIterator(): Traversable
        {
                return $this->backingIterator;
        }
}

function iter_search(mixed $needle, iterable $haystack, bool $strict = false): 
int|string|false
{
        foreach ( $haystack as $key => $value ) {
                if (
                        ( $strict && $value === $needle )
                        ||
                        ( ! $strict && $value == $needle )
                ) {
                        return $key;
                }
        }
        return false;
}

function array_search_range(
    mixed $needle,
    array $haystack,
    int $offset = 0,
    ?int $length = null,
    bool $strict = false,
): int|string|false {
        if ( $offset < 0 ) {
                $offset = count($haystack) + $offset;
        }
        if ( $length < 0 ) {
                $length = count($haystack) + $length - $offset;
        }

        $currentOffset = -1;
        foreach ( $haystack as $key => $value ) {
                $currentOffset++;
                if ( $currentOffset < $offset ) {
                        continue;
                }
                if ( $length !== null && $currentOffset >= $offset + $length ) {
                        break;
                }
                if (
                        ( $strict && $value === $needle )
                        ||
                        ( ! $strict && $value == $needle )
                ) {
                        return $key;
                }
        }
        return false;
}
```

Regards,

Rowan Tommins
[IMSoP]

Reply via email to