24

PHPの配列から空の要素を削除するという昔からの問題に対する単純で直接的な解決策を見つけることができないようです。

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

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

(データがもっとある場合は、そうではないかもしれませんが...)

上記のようになったら、処理後は完全に空にしておきたいです。

したがって、次のprint_r($array);ように出力されます。

Array ( )

実行しても同じ出力$arrayX = array_filter($arrayX);が得られます。しかし、私が調べたところはどこでも、これがPHP5で空の配列要素を削除する最も簡単な方法であることを示唆しています。 print_r

私も試し$arrayX = array_filter($arrayX,'empty_array');ましたが、次のエラーが発生しました:

警告:array_filter()[function.array-filter]:2番目の引数'empty_array'は有効なコールバックである必要があります

私は何が間違っているのですか?

4

8 に答える 8

46

array_map()を使用して、次のすべての配列にフィルターを適用してみてください$array

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

デモ:http ://codepad.org/xfXEeApj

于 2012-03-27T18:14:37.030 に答える
6

これを行う方法の例はたくさんあります。ドキュメントを試してみることができます(最初のコメントを参照)。

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が、要点はわかります。

于 2012-03-27T18:14:29.900 に答える
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などのみをテストすることもできます。

于 2015-01-15T23:44:43.647 に答える
4

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;
}
于 2014-01-23T21:02:53.447 に答える
4

試してみてください:

$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
(
)
于 2017-01-24T12:12:03.680 に答える
3

array_filter()デフォルトではタイプセンシティブではありません。これは、ゼロっぽい、false-y、null、空の値が削除されることを意味します。フォローする私のリンクは、この点を示しています。

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

静的2次元配列:このコードは、第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=[
    ['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',
  ),
)

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

于 2017-10-17T02:30:42.170 に答える
0

この質問がされたとき、PHPの最新バージョンは5.3.10でした。今日の時点で8.1.1になり、それ以来多くの変更がありました。以前の回答のいくつかは、コア機能の変更により、予期しない結果をもたらします。したがって、最新の回答が必要だと感じています。以下は、配列を反復処理し、空の文字列、空の配列、またはnullのいずれかである要素を削除します(したがって、falseと0が残ります)。これにより、空の配列がさらに存在する場合は、それらも削除されます。

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 );

于 2022-02-08T00:10:09.980 に答える
0

クラス内でヘルパーメソッドとして使用する場合:

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;
}
于 2022-02-19T16:41:46.423 に答える