【问题标题】:Filter recursive array and only remove NULL value过滤递归数组并仅删除 NULL 值
【发布时间】:2017-09-13 22:52:25
【问题描述】:

我想从递归数组中删除所有 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,但它只过滤简单数组而不是多维数组。我不想使用循环。

【问题讨论】:

  • 你从回调函数内部调用回调函数。为什么?
  • @diavolic bcz 我想过滤多维数组
  • 您使用 is_null() 函数,但它仅在您将变量设置为 NULL 时才有效。要获得所需的结果,请使用 empty()
  • empty() 删除 false 或 0 值,但我不想删除 0 或 false 值

标签: php arrays recursion multidimensional-array


【解决方案1】:

您可以将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);
    });
}

【讨论】:

    【解决方案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) 的内容。

    更新: 正如 cmets 中所述,带有迭代器的解决方案实际上并不适合此目的。

    array_walk_recursive函数的cmets中可以找到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

    【讨论】:

    • @Philipp,是的,我的错。我已经更新了我的答案。感谢您指出这一点。
    • 不错的解决方案。有没有办法让它删除具有特定键而不是值的子数组?
    • @DønerM.,谢谢。 $key 作为第二个参数传递给回调。所以你可以用它来匹配标准。
    【解决方案3】:

    这里您需要过滤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
                            (
                            )
    
                    )
    
            )
    
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-16
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多