[英]Recursively remove empty elements and subarrays from a multi-dimensional array
我似乎找不到一个简单直接的解决方案来解决从 PHP 中的 arrays 中删除空元素的古老问题。
我的输入数组可能如下所示:
Array ( [0] => Array ( [Name] => [EmailAddress] => ) )
(以此类推,如果有更多的数据,虽然可能没有...)
如果它看起来像上面那样,我希望它在我处理完之后完全是空的。
所以print_r($array);
output:
Array ( )
如果我运行$arrayX = array_filter($arrayX);
我仍然得到相同的print_r
output。然而,我看过的所有地方都表明这是在 PHP5 中删除空数组元素的最简单方法。
我也试过$arrayX = array_filter($arrayX,'empty_array');
但我收到以下错误:
警告:array_filter() [function.array-filter]:第二个参数“empty_array”应该是一个有效的回调
我究竟做错了什么?
尝试使用array_map()
将过滤器应用于$array
每个$array
:
$array = array_map('array_filter', $array);
$array = array_filter($array);
演示: http : //codepad.org/xfXEeApj
接受的答案并不完全符合 OP 的要求。 如果要递归删除所有评估为 false 的值,包括空数组,请使用以下函数:
function array_trim($input) {
return is_array($input) ? array_filter($input,
function (& $value) { return $value = array_trim($value); }
) : $input;
}
或者您可以根据需要更改退货条件,例如:
{ return !is_array($value) or $value = array_trim($value); }
如果您只想删除空数组。 或者您可以将条件更改为仅测试 "" 或 false 或 null 等...
有许多示例说明如何执行此操作。 您可以尝试docs ,一个(见第一条评论)。
function array_filter_recursive($array, $callback = null) {
foreach ($array as $key => & $value) {
if (is_array($value)) {
$value = array_filter_recursive($value, $callback);
}
else {
if ( ! is_null($callback)) {
if ( ! $callback($value)) {
unset($array[$key]);
}
}
else {
if ( ! (bool) $value) {
unset($array[$key]);
}
}
}
}
unset($value);
return $array;
}
当然,这个例子实际上并没有使用array_filter
但你明白了。
遵循 jeremyharris 的建议,这就是我需要对其进行更改以使其正常工作的方式:
function array_filter_recursive($array) {
foreach ($array as $key => &$value) {
if (empty($value)) {
unset($array[$key]);
}
else {
if (is_array($value)) {
$value = array_filter_recursive($value);
if (empty($value)) {
unset($array[$key]);
}
}
}
}
return $array;
}
尝试:
$array = array_filter(array_map('array_filter', $array));
例子:
$array[0] = array(
'Name'=>'',
'EmailAddress'=>'',
);
print_r($array);
$array = array_filter(array_map('array_filter', $array));
print_r($array);
输出:
Array
(
[0] => Array
(
[Name] =>
[EmailAddress] =>
)
)
Array
(
)
默认情况下, array_filter()
不是类型敏感的。 这意味着任何zero-ish 、false-y、null、空值都将被删除。 我要遵循的链接将证明这一点。
OP 的样本输入数组是二维的。 如果数据结构是静态的,则不需要递归。 对于想要从多维数组中过滤零长度值的任何人,我将提供静态二维方法和递归方法。
静态二维数组:此代码对第 2 级元素执行“零安全”过滤器,然后删除空子数组:( 请参阅此演示以了解此方法适用于不同(更棘手的)数组数据)
$array=[
['Name'=>'','EmailAddress'=>'']
];
var_export(
array_filter( // remove the 2nd level in the event that all subarray elements are removed
array_map( // access/iterate 2nd level values
function($v){
return array_filter($v,'strlen'); // filter out subarray elements with zero-length values
},$array // the input array
)
)
);
这是与单行代码相同的代码:
var_export(array_filter(array_map(function($v){return array_filter($v,'strlen');},$array)));
输出(最初由 OP 指定):
array (
)
*如果您不想删除空子array_filter()
,只需删除外部array_filter()
调用。
深度未知的多维数组的递归方法:当数组中的级别数未知时,递归是一种逻辑技术。 以下代码将处理每个子数组,同时删除零长度值和任何空子数组。 这是此代码的演示,其中包含一些示例输入。
$array=[
['Name'=>'','Array'=>['Keep'=>'Keep','Drop'=>['Drop2'=>'']],'EmailAddress'=>'','Pets'=>0,'Children'=>null],
['Name'=>'','EmailAddress'=>'','FavoriteNumber'=>'0']
];
function removeEmptyValuesAndSubarrays($array){
foreach($array as $k=>&$v){
if(is_array($v)){
$v=removeEmptyValuesAndSubarrays($v); // filter subarray and update array
if(!sizeof($v)){ // check array count
unset($array[$k]);
}
}elseif(!strlen($v)){ // this will handle (int) type values correctly
unset($array[$k]);
}
}
return $array;
}
var_export(removeEmptyValuesAndSubarrays($array));
输出:
array (
0 =>
array (
'Array' =>
array (
'Keep' => 'Keep',
),
'Pets' => 0,
),
1 =>
array (
'FavoriteNumber' => '0',
),
)
如果有人发现破坏了我的递归方法的输入数组,请将其发布(以最简单的形式)作为评论,我将更新我的答案。
问这个问题的时候,PHP的最新版本是5.3.10。 截至今天,现在是 8.1.1,此后发生了很多变化,一些较早的答案会提供意想不到的结果。 由于核心功能的变化,因此。 我觉得需要一个最新的答案,下面将遍历一个数组,删除任何空字符串、空数组或 null 的元素(因此 false 和 0 将保留),如果这导致任何更多空 arrays。它也会删除它们。
function removeEmptyArrayElements( $value ) {
if( is_array($value) ) {
$value = array_map('removeEmptyArrayElements', $value);
$value = array_filter( $value, function($v) {
// Change the below to determine which values get removed
return !( $v === "" || $v === null || (is_array($v) && empty($v)) );
} );
}
return $value;
}
要使用它,您只需调用removeEmptyArrayElements( $array );
如果在 class 内部用作辅助方法:
private function arrayFilterRecursive(array $array): array
{
foreach ($array as $key => &$value) {
if (empty($value)) {
unset($array[$key]);
} else if (is_array($value)) {
$value = self::arrayFilterRecursive($value);
}
}
return $array;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.