2012-03-27 9 views
15

空の要素をPHPの配列から削除するという古くからの問題に対する簡単な解決策は見当たりません。空の要素とサブアレイを多次元配列から再帰的に削除する

私の入力配列は次のようになります。

(存在しないかもしれませんが...、より多くのデータがあるかどうそしてそうで、)

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

それは上記のように見える場合は、I私がそれを処理した後にが完全に空になるようにします。

のでprint_r($array);は出力になります。私は$arrayX = array_filter($arrayX);を実行する場合

Array () 

私はまだ同じ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アレイ用に設定されています。 –

+0

サンプルの入力は可能ですか?あなたの質問を解釈するためのいくつかの方法があります。*「上記のように見える場合、私はそれを処理した後、完全に空であることを望みます。」*私は私を捨てています。空の配列にするには? –

+0

これは多次元配列です。 array_filterは1つのディメンションでのみ動作します。あなたはあなたの配列を反復処理し、最初に各反復にarray_filterを適用する必要があります。 – Nilpo

答えて

21

$array内のすべての列にフィルタを適用するarray_map()を使用してみてください:

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

デモ:私はそれを動作させるためにそれを変更するために必要な方法をjeremyharris'提案のフォローアップはhttp://codepad.org/xfXEeApj

+1

待機中です。*すべての項目が空の場合のみ配列全体を削除しますか? ?これはこれが何ではない。あなたは期待される出力をしてくださいサンプル入力を与えることができますか? –

+1

これはうまくいきません: -/ –

+0

あなたの質問とコメントの説明によると、そうする必要があります:http://codepad.org/FdfY5aqjすべての空のアイテムが削除されると、空の配列になります。これがあなたが望むものでないなら、期待される出力をいくつかのサンプル入力してください。あなたは他の配列から空を取り除くことの副作用に懸念していますか? –

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の最も深い配列の設定を解除することができず、フォローアップに失敗し、3重ネストされた構造をクリアしました。 – CodedMonkey

3

、これは次のようになります。

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が尋ねたものとまったく同じです。

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と評価すべての値を削除したい場合は、次の関数を使用します空の配列だけを削除したい場合。あるいは、条件を "" ""または "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()は型に敏感なのではないデフォルトです。つまり、がゼロの場合、false-y、null、空の値が削除されます。私のリンクはこの点を実証する。

OPのサンプル入力配列は2次元です。データ構造が静的な場合、再帰は必要ありません。多次元配列から長さゼロの値をフィルタリングしたい人は、静的な2次元の方法と再帰的な方法を提供します。

静的2次元のアレイ: このコードは、第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', 
), 
) 

誰もが私の再帰的な方法を破る入力配列を発見した場合は、コメントとして(最も単純な形式で)それを投稿してくださいと私は私の答えを更新します。

関連する問題