2017-04-18 27 views
4

我想从递归数组中删除所有空或空值,但不是false和0值。筛选递归数组,只删除NULL值

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用回调函数,但它只能过滤简单的数组不是多维数组。我不想使用循环。

+0

你的回调函数的调用内部的回调函数。为什么? – diavolic

+0

@diavolic bcz我想过滤多维数组 –

+0

您使用is_null()函数,但它只适用于将变量设置为NULL的情况。为了得到需要的结果,使用empty() – diavolic

回答

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)尽可能多的东西,你可以。

UPDATE: 因为它是在评论中指出,随着迭代器解决方案实际上并不适合用于这一目的。

在评论中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

+1

似乎,这也使数组变扁.. – Philipp

+0

@ Philipp,是的,我的不好。我已经更新了我的答案。感谢您指出这一点。 – sevavietl

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 
         (
         ) 

       ) 

     ) 

)