配列関連の処理ってforeachとかを使わないで1行でクールに書きたいと常々思いますよね。
今回は連想配列から欲しいキーだけを指定して部分集合を得るという方法について調べたのでメモです。
TL;DR
$subset = array_intersect_key($assoc_arr, array_flip([‘key1’, ‘key2’, …]));
説明
例えば
$cities = ['tokyo' => 1, 'osaka'=> 2, 'fukuoka' =>3];
Array
(
[tokyo] => 1
[osaka] => 2
[fukuoka] => 3
)
こんな連想配列からtokyo, osakaを指定して
Array
(
[tokyo] => 1
[osaka] => 2
)
を取得したいとします。
array_intersect_key(array $array1 , array $array2 [, array $… ])
公式リファレンス
複数の配列から、全ての配列に存在するキーのみを抜き出した配列を作成する関数です。
このとき、配列の値は第一引数の$array1のものが残ります。
(ちなみにPHPには配列と連想配列の区別がないので説明内で配列といっているものはキーが数値でも文字列でも同じです。以下同じ意味で使います。)
この関数だけを使う場合、
$subset = array_intersect_key($cities, ['tokyo' => null, 'osaka' => null]);
これによって実現できます。前述の通り第一引数の値が使われるので2個目の配列の値は何でも構いません。
ただ全部に => nullとか書くのはダルいです。そこを救ってくれるのが次のarray_flipです。
array_flip(array $array)
公式リファレンス
array_flipは配列のキーと値を反転するメソッドです。
print_r( ['tokyo', 'osaka'] );
Array
(
[0] => tokyo
[1] => osaka
)
こういう普通の順序の配列をarray_flipにかけると、キーと値を入れ替えて
print_r( array_flip(['tokyo', 'osaka']) );
Array
(
[tokyo] => 0
[osaka] => 1
)
配列の値だったものをキーにしてくれます。先程のarray_intersect_keyで第二引数以降の配列の値はなんでも良いので、こうして作成した文字列キーの配列はまさに求めていたものとなります。
組み合わせ
$subset = array_intersect_key($cities, array_flip(['tokyo', 'osaka']));
print_r($subset);
Array
(
[tokyo] => 1
[osaka] => 2
)
ただarray_flipで全部の配列のキーと値を逆転させるというのは本来的には必要無い行為なので、パフォーマンス的にはarray_flipが無いほうが良いかもしれません…。
参考
PHP array function that returns a subset for given keys – Stack Overflow
コメント