过滤递归数组并仅删除NULL值

时间:2017-04-18 07:41:15

标签: php arrays recursion multidimensional-array

我想从递归数组中删除所有null或空值但不删除false和0值。

function isNotNull($val) {
    if(is_array($val)) {
        $ret = array_filter($val, 'isNotNull');
        return $ret;
    } else {
        return (!is_null($val) && $val !== '');
   }

}

$ arr = array_filter($ arr,'isNotNull');

输入:

$arr = array(
"stringKey" => "Abc",
"boolKey" => false,
"zeroKey" => 0,
"blankKey" => '',
"newArr" => array(
    "stringKey2"=>"Abc2", 
    "boolKey2"=>false, 
    "zeroKey2" => 0, 
    "blankKey2"=>"", 
    "blankArr" => array()
    )
);

这给出了输出:

Array
(
    [stringKey] => Abc
    [boolKey] => 
    [zeroKey] => 0
    [newArr] => Array
        (
            [stringKey2] => Abc2
            [boolKey2] => 
            [zeroKey2] => 0
            [blankKey2] => 
            [blankArr] => Array
                (
                )
        )
)

但我想低估输出:

 Array
(
    [stringKey] => Abc
    [boolKey] => 
    [zeroKey] => 0
    [newArr] => Array
        (
            [stringKey2] => Abc2
            [boolKey2] => 
            [zeroKey2] => 0
        )
)

我使用了带回调函数的array_filter,但它只过滤了简单数组而不是多维数组。我不想使用循环。

3 个答案:

答案 0 :(得分:3)

您可以在递归调用函数中组合array_maparray_filter。这样的事情对你有用。

function filterNotNull($array) {
    $array = array_map(function($item) {
        return is_array($item) ? filterNotNull($item) : $item;
    }, $array);
    return array_filter($array, function($item) {
        return $item !== "" && $item !== null && (!is_array($item) || count($item) > 0);
    });
}

答案 1 :(得分:2)

不要自己重新发明递归。您可以使用RecursiveCallbackFilterIterator

$iterator = new RecursiveIteratorIterator(
    new RecursiveCallbackFilterIterator(
        new RecursiveArrayIterator($arr),
        function ($value) {
            return $value !== null && $value !== '';
        }
    )
);

$result = iterator_to_array($iterator);

这是working demo

您应该尝试尽可能多地使用 Standard PHP Library (SPL) 中的内容。

<强>更新 正如评论中所述,使用迭代器的解决方案实际上并不适用于此目的。

array_walk_recursive函数的评论中,您可以找到walk_recursive_remove函数的实现:

function walk_recursive_remove (array $array, callable $callback) { 
    foreach ($array as $k => $v) { 
        if (is_array($v)) { 
            $array[$k] = walk_recursive_remove($v, $callback); 
        } else { 
            if ($callback($v, $k)) { 
                unset($array[$k]); 
            } 
        } 
    } 

    return $array; 
} 

这种递归函数的通用版本采用回调形式的标准。有了这个功能,你可以删除这样的空元素:

$result = walk_recursive_remove($arr, function ($value) {
    return $value === null || $value === '';
});

这是working demo

答案 2 :(得分:0)

在这里,您需要过滤empty string的数组。在下面的代码中,您可以添加任何检查以递归过滤它。希望它能正常工作。

Try this code snippet here

<?php

ini_set('display_errors', 1);
//Using more complexed sample array for filter it.
$arr = array(
    "stringKey" => "Abc",
    "boolKey" => false,
    "zeroKey" => 0,
    "blankKey" => '',
    "newArr" => array(
        "stringKey2" => "Abc2",
        "boolKey2" => false,
        "zeroKey2" => 0,
        "blankKey2" => "",
        "blankArr" => array(
            "blankString"=>"",
            "zeroKey"=>0,
            "blankArr3"=>array()
        )
    )
);

$result=recursiveFilter($arr);
print_r($result);


function recursiveFilter($value)
{
    foreach ($value as $key => $value1)
    {
        if ($value1 === "")  unset($value[$key]);//you can add no. of conditions here.
        else if (is_array($value1)) $value[$key] = recursiveFilter($value1);
    }
    return $value;
}

<强>输出:

Array
(
    [stringKey] => Abc
    [boolKey] => 
    [zeroKey] => 0
    [newArr] => Array
        (
            [stringKey2] => Abc2
            [boolKey2] => 
            [zeroKey2] => 0
            [blankArr] => Array
                (
                    [zeroKey] => 0
                    [blankArr3] => Array
                        (
                        )

                )

        )

)