rfc:array_find

This is an old revision of the document!


PHP RFC: array_find

Introduction

This RFC proposes the addition of two new functions array_find and array_find_key, which return the first element for which a predicate callback returns true.

There are currently lots of functions in PHP for modifying or filtering arrays. However, there is no simple function to search an array with a callback and return the first result. Implementing this in userland is relatively simple (either via a loop or via array_filter combined with reset), but the function is often required, so this type of function is often built [1]. Therefore there is a reason to include this function as standard with the next PHP version. In addition, the implementation of the function is similar to array_filter and relatively trivial to implement, so the maintenance effort should be low.

Proposal

This RFC proposes to add two new function, array_find and array_find_key and a new enum ArrayCallableParameter which is used, to determine which parameters are passed to the given callback.

array_find

 
function array_find(array $array, callable $callback, ArrayCallableParameter $callableParameter = ArrayCallableParameter::UseValue): mixed {
    foreach ($array as $key => $value) {
        $parameters = [$value];
 
        if ($callableParameter === ArrayCallableParameter::UseBoth) {
            $parameters[] = $key;
        } else if ($callableParameter === ArrayCallableParameter::UseKey) {
            $parameters = [$key];
        }
 
        if ($callback(...$parameters)) {
            return $value;
        }
    }
 
    return null;
}

Parameters

array $array

The array that should be searched.

callable $callback

The callback function to call to check each element. Which parameter are given to the callback is specified by the third parameter of this function. If this function returns true, the value is returned from array_find and the callback will not be called for further elements.

ArrayCallableParameter $callableParameter

This parameters defines, which parameters are given to the callback.

Return Value

The function returns the first array value for which the $callback returns true. If no matching entry is found, the function returns NULL

Examples

$array = [
    'a' => 'dog',
    'b' => 'cat',
    'c' => 'cow',
    'd' => 'duck',
    'e' => 'goose',
    'f' => 'elephant'
];
 
// Find the first animal with a name longer than 4 characters.
var_dump(array_find($array, function (string $value) {
    return strlen($value) > 4;
})); // string(5) "goose"
 
// Find the first animal whose name begins with f. 
var_dump(array_find($array, function (string $value) {
    return str_starts_with($value, 'f'); 
})); // NULL
 
// Find the first animal where the array key is the first symbol of the animal.
var_dump(array_find($array, function (string $value, $key) {
   return $value[0] === $key;
}, ArrayCallableParameter::UseBoth)); // string(3) "cow"
 
// Find the first animal where the array key matching a RegEx.
var_dump(array_find($array, function ($key) {
   return preg_match('/^([a-f])$/', $key);
}, ArrayCallableParameter::UseKey)); // string(3) "dog"

array_find_key

function array_find_key(array $array, callable $callback, ArrayCallableParameter $callableParameter = ArrayCallableParameter::UseValue): mixed {
    foreach ($array as $key => $value) {
        $parameters = [$value];
 
        if ($callableParameter === ArrayCallableParameter::UseBoth) {
            $parameters[] = $key;
        } else if ($callableParameter === ArrayCallableParameter::UseKey) {
            $parameters = [$key];
        }
 
        if ($callback(...$parameters)) {
            return $key;
        }
    }
 
    return null;
}

Parameters

array $array

The array that should be searched.

callable $callback

The callback function to call to check each element. Which parameter are given to the callback is specified by the third parameter of this function. If this function returns true, the key is returned from array_find_key and the callback will not be called for further elements.

ArrayCallableParameter $callableParameter

This parameters defines, which parameters are given to the callback.

Return Value

The function returns the first array key for which the $callback returns true. If no matching entry is found, the function returns NULL

Examples

$array = [
    'a' => 'dog',
    'b' => 'cat',
    'c' => 'cow',
    'd' => 'duck',
    'e' => 'goose',
    'f' => 'elephant'
];
 
// Find the first animal with a name longer than 4 characters.
var_dump(array_find_key($array, function (string $value) {
    return strlen($value) > 4;
})); // string(1) "e"
 
// Find the first animal whose name begins with f. 
var_dump(array_find_key($array, function (string $value) {
    return str_starts_with($value, 'f'); 
})); // NULL
 
// Find the first animal where the array key is the first symbol of the animal.
var_dump(array_find_key($array, function (string $value, $key) {
   return $value[0] === $key;
}, ArrayCallableParameter::UseBoth)); // string(1) "c"
 
// Find the first animal where the array key matching a RegEx.
var_dump(array_find_key($array, function ($key) {
   return preg_match('/^([a-f])$/', $key);
}, ArrayCallableParameter::UseKey)); // string(1) "a"

ArrayCallableParameter

Add a new enum ArrayCallableParameter to define which parameter the callable for the new array_* functions should receive. The enum has three values:

  • UseValue to pass only the value of the array to the given callback
  • UseKey to pass only the key of the array to the given callback
  • UseBoth to pass the value as first parameter and the key as a second parameter to the given callback
enum ArrayCallableParameter {
    case UseValue;
    case UseKey;
    case UseBoth;
}

Backward Incompatible Changes

Functions created by the user and named array_find or array_find_key lead to a PHP error with the new version. A quick GitHub search shows, that there a 656 results defining the symbol array_find for the language PHP. Looking at the search results I estimate about 30% of these results are functions that are not located in a namespace and are not part of a class. array_find_key is defined 28 times on GitHub. The enum ArrayCallableParameter is never defined on GitHub.

Proposed PHP Version(s)

PHP 8.4

RFC Impact

To SAPIs

None.

To Existing Extensions

None.

To Opcache

None.

New Constants

None.

php.ini Defaults

None.

Open Issues

None.

Unaffected PHP Functionality

This RFC only adds two new functions and an enum to PHP and only affects previously defined functions which are named as the proposed function or enum.

Implementation

References

rfc/array_find.1713895672.txt.gz · Last modified: 2024/04/23 18:07 by josh