array_filter($array, $callback)は、$callbackがtrue(またはtrueに変換される値)を返した$arrayの要素を返します。配列が先、コールバックが後で、残った要素は元のキーを保ちます。
結果のキーは1, 3, 5, 7で、元の配列でそれらの値があった位置です。この点は見た目以上に重要で、2つ後の節でその扱い方を説明します。
配列から空の値を取り除く
コールバックなしでarray_filterを呼ぶと、falseに変換される値をすべて取り除きます。空文字列、null、false、0、"0"、空の配列です。explode()の結果やフォームの項目のリストをきれいにするいちばん手早い方法です。
最初の結果では"0"と0も消えていますが、これらは本当のデータであることがよくあります(数量の0、郵便番号の数字)。0が正当な答えなら、2つ目の呼び出しのようにコールバックを自分で書きましょう。PHPが空とみなす値の完全な一覧はemptyのページにあります。
array_valuesで結果の番号を振り直す
キーが保たれるので、絞り込んだリストには欠番ができることがあります。すると0からのforループは存在しないキーにぶつかり、json_encodeは結果をJSON配列ではなくJSONオブジェクトにします。array_values()で番号を振り直します。
ARRAY_FILTER_USE_KEYでキーによって絞り込む
3つ目の引数で、コールバックが受け取るものを選びます。ARRAY_FILTER_USE_KEYはキーだけを渡し、ARRAY_FILTER_USE_BOTHは値とキーをこの順で渡します。
すでにわかっている決まったキーの集合を残すなら、array_intersect_key($config, array_flip(['db_host', 'db_port']))がコールバックなしで同じことをします。
多次元配列を絞り込む
実際のデータのほとんどは行のリストです。コールバックは1回に1行を受け取るので、必要なフィールドを判定します。
$maxPriceを変えて、もう一度実行してみてください。そのあと名前だけを取り出すには、結果をarray_columnに渡します:array_column($affordable, 'name')。
絞り込んで、変換して、集計する
array_filterは要素を選び、array_mapは要素を変え、array_reduceは配列を1つの値にまとめます。array_reduce($array, $callback, $initial)は、途中までの合計と次の要素でコールバックを呼び出します。
単純な合計ならarray_sum($totals)のほうが短く書けます。array_reduceが役に立つのは、結果がそれ以外のもの、たとえば文字列、グループごとの件数、いちばん大きな行のときです。
よくあるミス:array_filterの中で値を変更する
コールバックの戻り値は、要素を残すかどうかを決めるだけです。それ以外に計算したものは捨てられるので、次のコードは何もtrimしません。
array_mapで変換してから絞り込み、きれいなリストが必要ならarray_valuesを加えましょう。
よくある質問
PHPで配列から空の値を取り除くには?
コールバックなしでarray_filter($array)を呼びます。falseと評価される値(""、null、false、0、"0"、[])をすべて取り除きます。空文字列とnullだけを取り除いて0を残すには、コールバックを渡します:array_filter($array, fn($v) => $v !== '' && $v !== null)。
array_filterが古いキーを保つのはなぜですか?
array_filterは番号を振り直しません。残した要素は元のキーのままなので、リストが[0 => 'a', 2 => 'c']のように返ってくることがあります。array_values()で包むと再び0, 1, 2になり、json_encodeもJSONオブジェクトではなくJSON配列を出力するようになります。
PHPで配列をキーで絞り込むには?
3つ目の引数にARRAY_FILTER_USE_KEYを渡すと、コールバックは値の代わりにキーを受け取ります:array_filter($arr, fn($k) => str_starts_with($k, 'db_'), ARRAY_FILTER_USE_KEY)。値とキーの両方を受け取るにはARRAY_FILTER_USE_BOTHを使います。
array_filterとarray_mapの違いは何ですか?
array_filterはどの要素を残すかを決め、それらを変更せずに返します。array_mapはすべての要素を変更し、同じ数の要素を返します。両方を行うには連鎖させます:array_map('strtoupper', array_filter($arr))。