I need to remove empty entries on multilevel arrays. For now I can remove entries with empty sub-arrays, but not empty arrays... confused, so do I... I think the code will h
I think this should solve your problem.
$retArray =array_filter($array, arrayFilter);
function arrayFilter($array) {
if(!empty($array)) {
return array_filter($array);
}
}
Recursively clear multidimensional array of empty'ish items:
final class ArrayCleaner
{
public static function clean(array $value): array
{
foreach ($value as $k => $v) {
if (\is_array($v)) {
$value[$k] = self::clean($v);
if (0 == \count($value[$k])) {
unset($value[$k]);
}
} elseif (empty($v)) {
unset($value[$k]);
}
}
return $value;
}
}
Unit test:
final class ArrayCleanerTest
{
public function testItCleans(): void
{
$input = [
'empty_string_to_remove' => '',
'empty_int_to_remove' => 0,
'empty_string_number_to_remove' => '0',
'value_to_keep' => 5,
'empty_array_to_remove' => [],
'empty_array_of_empty_arrays_to_remove' => [
'one' => [],
'two' => [],
'three' => [false, null, '0'],
],
'array_to_keep_1' => [
'value' => 1,
],
'array_to_keep_2' => [
'empty_to_remove' => [],
'array_to_keep' => ['yes'],
],
];
$expected = [
'value_to_keep' => 5,
'array_to_keep_1' => [
'value' => 1,
],
'array_to_keep_2' => [
'array_to_keep' => ['yes'],
],
];
$this->assertEquals($expected, ArrayCleaner::clean($input));
}
}
Working proof of concept at 3v4l.org
Here is my solution, it will remove exactly specified list of empty values recursively:
/**
* Remove elements from array by exact values list recursively
*
* @param array $haystack
* @param array $values
*
* @return array
*/
function array_remove_by_values(array $haystack, array $values)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = array_remove_by_values($haystack[$key], $values);
}
if (in_array($haystack[$key], $values, true)) {
unset($haystack[$key]);
}
}
return $haystack;
}
You can use it like this:
$clean = array_remove_by_values($raw, ['', null, []]);
Note, it removes empty sub arrays if you pass []
as one of values.
My function:
function removeEmptyItems($item)
{
if (is_array($item)) {
$item = array_filter($item, 'removeEmptyItems');
}
return !empty($item);
}
$nonEmpty = array_filter($raw, 'removeEmptyItems');
If you want array_filter to work recursively, you'll need to make sure that the subsequent calls may edit the deeper nested items of the array. Short: You'll need to pass it by reference:
function removeEmptyItems(&$item) {
if (is_array($item) && $item) {
$item = array_filter(&$item, 'removeEmptyItems');
}
return !!$item;
}
Try this code:
<?php
function array_remove_empty($haystack)
{
foreach ($haystack as $key => $value) {
if (is_array($value)) {
$haystack[$key] = array_remove_empty($haystack[$key]);
}
if (empty($haystack[$key])) {
unset($haystack[$key]);
}
}
return $haystack;
}
$raw = array(
'firstname' => 'Foo',
'lastname' => 'Bar',
'nickname' => '',
'birthdate' => array(
'day' => '',
'month' => '',
'year' => '',
),
'likes' => array(
'cars' => array('Subaru Impreza WRX STi', 'Mitsubishi Evo', 'Nissan GTR'),
'bikes' => array(),
),
);
print_r(array_remove_empty($raw));