PHP - 如何递归删除数组的空条目?

时间:2011-10-08 11:40:10

标签: php arrays array-filter

我需要删除多级数组上的空条目。现在我可以删除带有空子数组的条目,但不能删除空数组...混淆,所以我...我认为代码将有助于更好地解释......

<?php

/**
 * 
 * This function remove empty entries on arrays
 * @param array $array
 */
function removeEmptysFromArray($array) {

    $filtered = array_filter($array, 'removeEmptyItems');
    return $filtered;
}

/**
 * 
 * This is a Callback function to use in array_filter()
 * @param array $item
 */
function removeEmptyItems($item) {

    if (is_array($item)) {
        return array_filter($item, 'removeEmptyItems');
    }

    if (!empty($item)) {
        return true;  
    }
}


$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(removeEmptysFromArray($raw));

?>

好的,此代码将删除“nickname”,“birthdate”,但不会删除具有空数组的“自行车”。

我的问题是......如何删除“自行车”条目?

最诚挚的问候,

抱歉我的英文......

6 个答案:

答案 0 :(得分:29)

试试这段代码:

<?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));

答案 1 :(得分:2)

我认为这应该可以解决您的问题。

$retArray =array_filter($array, arrayFilter);

function arrayFilter($array) {
     if(!empty($array)) {
         return array_filter($array);
     }
}

答案 2 :(得分:0)

这是我的解决方案,它将以递归方式删除指定的空值列表:

&

你可以像这样使用它:

/**
 * 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;
}

注意,如果将$clean = array_remove_by_values($raw, ['', null, []]); 作为值之一传递,它将删除空子数组。

答案 3 :(得分:0)

递归清除空物品的多维数组:

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;
    }
}

单元测试:

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

答案 4 :(得分:0)

我的功能:

function removeEmptyItems($item)
{
    if (is_array($item)) {
        $item = array_filter($item, 'removeEmptyItems');
    }
    return !empty($item);
}

$nonEmpty = array_filter($raw, 'removeEmptyItems');

答案 5 :(得分:-2)

如果希望array_filter以递归方式工作,则需要确保后续调用可以编辑数组中较深层的嵌套项。简短:您需要通过引用传递它:

function removeEmptyItems(&$item) {
    if (is_array($item) && $item) {
        $item = array_filter(&$item, 'removeEmptyItems');
    }

    return !!$item;
}