2012-03-27 72 views
15

我似乎无法找到一个简单直接的解决方案,解决PHP中从数组中删除空元素的古老问题。递归删除多维数组中的空元素和子阵列

我输入数组可能看起来像这样:

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

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

如果它看起来像上述情况,我想要它在我处理它后成为完全清空

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

Array () 

如果我跑$arrayX = array_filter($arrayX);我仍然得到相同print_r输出。但是,我看到的每个地方都表明,这是删除PHP5中空数组元素的最简单方法。

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

Warning: array_filter() [function.array-filter]: The second argument, 'empty_array', should be a valid callback

我在做什么错?

+0

array_filter设置为1D数组。 – 2012-03-27 18:14:28

+0

您能提供样品输入,请预期输出吗?有几种不同的方式来解释你的问题,*“如果它看起来像上面那样,我希望它在我处理它之后是完全空的。”*将我抛弃,你希望它完全消失还是成为一个空阵列? – 2012-03-27 18:19:57

+0

这是一个多维数组。 array_filter只能在一个维度上工作。你需要遍历你的数组,并首先将array_filter应用到每个迭代。 – Nilpo 2012-03-27 18:20:54

回答

21

尝试使用array_map()应用过滤器的每一个阵列中$array

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

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

+1

等待等待,是否只有在* all *项为空时才删除整个数组?这不是这样做的。你能给样品输入,请预期输出吗? – 2012-03-27 18:17:08

+1

没有。这是行不通的: -/ – 2012-03-27 18:19:57

+0

根据你的问题和评论中的说明,是的它应该:http://codepad.org/FdfY5aqj当所有的空项目被移除时,你最终会得到一个空数组。如果这不是你想要的,请给出一些预期输出的示例输入。你是否担心从其他数组中删除空容器的副作用? – 2012-03-27 18:28:49

7

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

+0

此代码无法取消设置最长的0长度数组,并且无法跟进并清除它所在的三重嵌套结构 – CodedMonkey 2014-01-23 20:27:58

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

接受的答案并不完全是OP所要求的。如果你想递归地删除值为false,包括空数组ALL值,然后使用以下功能:

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等...

2

尝试:

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

array_filter()不是类型敏感默认。这意味着任何zero-ish,false-y,null,空值将被删除。我遵循的链接将证明这一点。

OP的样本输入数组是2维的。如果数据结构是静态的,那么递归是不必要的。对于任何想要从多维数组中过滤零长度值的人,我会提供一个静态2-dim方法和递归方法。

静态2维数组: 该代码执行对第二级元素“零安全”过滤器,然后除去空子阵列:(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', 
), 
) 

如果有人发现了一个输入数组,打破我的递归方法,请张贴(最简单的形式)的评论,我会更新我的答案。