Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?
Organization

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

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"
      }
    }
  }
}
*/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?