过滤递归数组并仅删除 NULL 值
Posted
技术标签:
【中文标题】过滤递归数组并仅删除 NULL 值【英文标题】:Filter recursive array and only remove NULL value 【发布时间】: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 值 【参考方案1】:您可以将array_map
和array_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
(
)
)
)
)
【讨论】:
以上是关于过滤递归数组并仅删除 NULL 值的主要内容,如果未能解决你的问题,请参考以下文章