Skip to content

Instantly share code, notes, and snippets.

@benjamw
Last active December 5, 2022 10:34
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benjamw/1690140 to your computer and use it in GitHub Desktop.
Save benjamw/1690140 to your computer and use it in GitHub Desktop.
PHP array_filter_recursive function
<?php
/**
* Exactly the same as array_filter except this function
* filters within multidimensional arrays
*
* @param array $array
* @param callable|null $callback optional filter callback function
* @param bool $remove_empty_arrays optional flag removal of empty arrays after filtering
*
* @return array filtered array
*/
function array_filter_recursive(array $array, callable $callback = null, bool $remove_empty_arrays = false): array {
foreach ($array as $key => & $value) { // mind the reference
if (is_array($value)) {
$value = call_user_func_array(__FUNCTION__, array($value, $callback, $remove_empty_arrays));
if ($remove_empty_arrays && ! (bool) $value) {
unset($array[$key]);
}
}
else {
if ( ! is_null($callback) && ! $callback($value)) {
unset($array[$key]);
}
elseif ( ! (bool) $value) {
unset($array[$key]);
}
}
}
unset($value); // kill the reference
return $array;
}
@vanderlee
Copy link

Fix $remove_empty_arrays in recursion and added $key to callback argument list:

/** function array_filter_recursive
 *
 *      Exactly the same as array_filter except this function
 *      filters within multi-dimensional arrays
 *
 * @param array
 * @param string optional callback function name
 * @param bool optional flag removal of empty arrays after filtering
 * @return array merged array
 */
function array_filter_recursive($array, $callback = null, $remove_empty_arrays = false)
{
    foreach ($array as $key => & $value) { // mind the reference
        if (is_array($value)) {
            $value = array_filter_recursive($value, $callback, $remove_empty_arrays);
            if ($remove_empty_arrays && !(bool) $value) {
                unset($array[$key]);
            }
        } else {
            if (!is_null($callback) && !$callback($value, $key)) {
                unset($array[$key]);
            } elseif (!(bool) $value) {
                unset($array[$key]);
            }
        }
    }
    unset($value); // kill the reference
    return $array;
}

@Sparviero-Sughero
Copy link

or you can use call_user_func_array to "free" the function's name

/** function array_filter_recursive
 *
 *      Exactly the same as array_filter except this function
 *      filters within multi-dimensional arrays
 *
 * @param array
 * @param string optional callback function name
 * @param bool optional flag removal of empty arrays after filtering
 * @return array merged array
 */
function array_filter_recursive($array, $callback = null, $remove_empty_arrays = false) {
  foreach ($array as $key => & $value) {
    if (is_array($value)) {
      $value = call_user_func_array(__FUNCTION__, array($value, $callback, $remove_empty_arrays));
      if ($remove_empty_arrays && ! (bool) $value) {
        unset($array[$key]);
      }
    }
    else {
      if ( ! is_null($callback) && ! $callback($value)) {
        unset($array[$key]);
      }
      elseif ( ! (bool) $value) {
        unset($array[$key]);
      }
    }
  }
  unset($value);
  return $array;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment