以递归方式从多维数组中删除空元素和子数组

时间:2012-03-27 18:09:56

标签: php arrays multidimensional-array filtering is-empty

我似乎无法找到一个简单,直接的解决方案来解决从PHP中的数组中删除空元素的古老问题。

我的输入数组可能如下所示:

Array ( [0] => Array ( [Name] => [EmailAddress] => ) ) 

(依此类推,如果有更多数据,虽然可能没有...)

如果它看起来如上所示,我希望它在处理完毕后完全为空

所以print_r($array);会输出:

Array ( )

如果我运行$arrayX = array_filter($arrayX);,我仍然可以获得相同的 print_r输出。我看过的每个地方都建议这是在PHP5中删除空数组元素的最简单方法。

我也试过了$arrayX = array_filter($arrayX,'empty_array');但是我收到了以下错误:

  

警告:array_filter()[function.array-filter]:第二个参数'empty_array'应该是有效的回调

我做错了什么?

6 个答案:

答案 0 :(得分:26)

尝试使用array_map()将过滤器应用于$array中的每个数组:

$array = array_map('array_filter', $array);
$array = array_filter($array);

演示:http://codepad.org/xfXEeApj

答案 1 :(得分:5)

有很多如何做到这一点的例子。您可以尝试使用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,但你明白了。

答案 2 :(得分:5)

接受的答案并不完全符合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等等...

答案 3 :(得分:3)

跟进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;
}

答案 4 :(得分:1)

尝试:

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

答案 5 :(得分:1)

默认情况下,

array_filter()对类型不敏感。这意味着将删除任何 zero-ish ,false-y,null,空值。我的关注链接将证明这一点。

OP的样本输入数组是二维的。如果数据结构是静态的,则不需要递归。对于想要从多维数组中过滤零长度值的人,我将提供静态2-dim方法和递归方法。

静态2-dim数组: 此代码执行"零安全"过滤第二级元素,然后删除空子数组:(See this demo to see this method work with different (trickier) array data

$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()电话。

未知深度的多维数组的递归方法:当数组中的级别数未知时,递归是一种逻辑技术。以下代码将处理每个子数组,删除零长度值和任何空子数组。 Here is a demo of this code with a few sample inputs.

$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',
  ),
)

如果有人发现破坏我的递归方法的输入数组,请将其(以最简单的形式)发布为评论,我会更新我的答案。