Add array_search_range() function - #23325
Conversation
| max_count = length ? length : zend_hash_num_elements(ht); | ||
|
|
||
| ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, key_str, entry) { | ||
| if (i >= offset && (i < offset + max_count)) { |
There was a problem hiding this comment.
It looks like this is still going to iterate the whole array, and only the comparison is optimised. That's still going to be inefficient for very large arrays.
Completely ignoring the elements after the offset is trivial:
| if (i >= offset && (i < offset + max_count)) { | |
| if ( i < offset ) { | |
| continue; | |
| } elseif ( i >= offset + max_count ) { | |
| break; | |
| } else { |
But if you look at the implementation of array_slice, it has extra optimisations for finding the start offset - some arrays are laid out sequentially in memory, so the memory address can be calculated without iterating.
There was a problem hiding this comment.
Thanks for pointing that out — that’s a really good catch, and I can see how array_slice’s handling of packed arrays is the right way to think about the offset lookup.
You’re absolutely right that the simpler range check still walks the whole array, and skipping past the offset (or breaking out once we pass offset + max_count) is the correct optimisation. I’ll apply that.
Appreciate you taking the time to review this
Add array_search_range() function
This PR adds a new array_search_range() function to the PHP standard library.
Function signature
array_search_range(mixed $needle, array $haystack, int $offset = 0, ?int $length = null, bool $strict = false): int|string|false
Description
array_search_range() searches a portion of the array for a given value and returns the first corresponding key if successful, or false if not found.
It extends the existing array_search() function with two additional parameters:
Examples
$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 2, 'e' => 1];
array_search_range(2, $array); // "b"
array_search_range(2, $array, 2); // "d"
array_search_range(2, $array, 0, 2); // "b"
array_search_range(1, $array, -2); // "e"