LoginSignup
0
1

More than 3 years have passed since last update.

[PHP]多次元配列から要素をフィルタリングする

Posted at

PHPには、array_filter関数というものがあります。
配列に入っている要素を特定の条件でフィルタリングするための関数で、空の要素を排除したい時や偶数を取り出したい時などに使ったりします。

例えば以下のコードを実行した場合、2番目(空文字)、4番目(null)、6番目(false)の要素が削除され、値が入っているものだけを取り出すことができます。

$array = [
    'aaa',
    '',
    'bbb',
    null,
    'ccc',
    false,
];

var_dump(array_filter($array));

/* 実行結果
array(3) {
  [0]=>
  string(3) "aaa" 
  [2]=>
  string(3) "bbb" 
  [4]=>
  string(3) "ccc" 
}
*/

しかし、array_filter関数は多次元配列には対応していないので、
多次元配列に対応した関数を作りました。

/**
 * コールバック関数を使用して、配列の要素をフィルタリングする(多次元配列対応)
 *
 * @param array $array 処理する配列
 * @param callable $callback 使用するコールバック関数
 * @param bool $unset_empty_array 空の配列を削除するか否か
 * @return array $array フィルタリングされた配列
 */
function array_filter_recursive($array, $callback=null, $unset_empty_array=false)
{
    if (is_array($array)) {
        // コールバック関数が未指定の場合
        if (!$callback) {
            // コールバック関数を指定する
            $callback = function($value) {
                return !empty($value); 
            };
        }
        foreach (array_keys($array) as $key) {
            if (is_array($array[$key])) {
                // 多次元配列の場合は再帰処理を行う
                $array[$key] = array_filter_recursive($array[$key], $callback, $unset_empty_array);
                // $unset_empty_arrayがtrueかつ配列が空なら削除
                if ($unset_empty_array && empty($array[$key])) {
                    unset($array[$key]);
                }
            // 指定したコールバック関数をコールし、戻り値がfalseなら削除
            } else if (!call_user_func($callback, $array[$key])) {
                unset($array[$key]);
            }
        }
    }
    return $array;
}

ではさっそく、先ほど作った関数を使ってみたいと思います。

実行結果は以下の通りで、ちょっと歪な多次元配列でも空の要素が全て削除されることが確認できました。

$array = [
    [],
    [
        'aaa',
        '',
        'bbb',
    ],
    [
        [
            null,
            'ccc',
            'ddd',
        ],
        [],
        [
            [],
            [
                'eee',
                'fff',
                false,
            ],
        ],
    ],
];

var_dump(array_filter_recursive($array, 'strlen', true));

/* 実行結果
array(2) {
  [1]=>
  array(2) {
    [0]=>
    string(3) "aaa"
    [2]=>
    string(3) "bbb"
  }
  [2]=>
  array(2) {
    [0]=>
    array(2) {
      [1]=>
      string(3) "ccc"
      [2]=>
      string(3) "ddd"
    }
    [2]=>
    array(1) {
      [1]=>
      array(2) {
        [0]=>
        string(3) "eee"
        [1]=>
        string(3) "fff"
      }
    }
  }
}
*/
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1