Skip to content

Instantly share code, notes, and snippets.

@benjamw
Last active June 11, 2024 09:41
Show Gist options
  • 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;
}
@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;
}

@tiria-fred
Copy link

In addition if you define a callback, maybe you want some "empty" values to be returned, so you need to avoid elseif :

/**
 * 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)) {
				if ( ! $callback($value)) {
					unset($array[$key]);
				}
			}
			elseif ( ! (bool) $value) {
				unset($array[$key]);
			}
		}
	}
	unset($value); // kill the reference

	return $array;
}

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