今日 UnitTest の実装を考えてたんだけど、素直にやると全部ぶん回すような処理になりそうな気配があった。なので、「そういえば PHP にもフィルターかけれるようなのあったよな?」と思い出し、array_filter
を使った実装で UnitTest を書いた。
忘れないうちに備忘録。
公式マニュアル
公式には以下のコードがサンプルとして載っている。
<?php
function odd($var)
{
// 渡された整数が奇数かどうかを返します
return($var & 1);
}
function even($var)
{
// 渡された整数が偶数かどうかを返します
return(!($var & 1));
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
お、、、おう??
これ、正直に言ってめっちゃわかりにくい。なんで第二引数がstring
なの?とか、function
には何が引数として渡ってるの?とかいう部分が読み取りづらい(※個人の感想です)。
サンプルコード改
なのでこれをクロージャで書いてあげると、読み取りやすくなる(と思う)。
<?php
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
echo "Odd :\n";
print_r(array_filter($array1, function ($arr) {
return($arr & 1);
}));
echo "Even:\n";
print_r(array_filter($array2, function ($arr) {
return(!($arr & 1));
}));
クロージャーの引数$arr
には、$array1
もしくは$array2
の値が一つづつ渡ってくる(気になる方はvar_dump
などで出力してみて)ので、$array1
なら 1,2,3,4,5 が渡ってくるし、$array2
なら 6,7,8,9,10,11,12 が渡ってくる。
クロージャーにあまり馴染みがなければ逆に難しいのかもしれない(PHP でクロージャーってそんな書かないもんね…)が、僕的にはこっちの書き方の方が馴染むし、見通しもよく感じる。
クロージャーについては、公式マニュアルがあるので、合わせて読むと理解が深まるはずだ。
もちろん、普通のクロージャーと同じく、こういう場合でもuse
文を書くことで変数を持ってくることができる(サンプルがしょぼくて申し訳ない)。
<?php
$val = 10;
$array = array(6, 7, 8, 9, 10, 11, 12);
echo "Same :\n";
print_r(array_filter($array, function ($arr) use ($val) {
return($arr === $val);
}));
こうやってまとめたから、きっともう忘れない、はず(少なくともブログに書いたことは忘れない)。
余談
直近で Flutter/Dart のプロジェクトをやっていたこともあって、こういう functional っぽい感じが好きになった。