LAMPな会社に来て1年半がたち、1ヶ月前にPHPデビューをしました。
で、やっぱりいろいろツライところがあったのと、風呂あがりに思い立ったのと、いろいろと触発されたところあって、PHPでLINQっぽく配列操作ができるWrapperを作ってみました。
実際に、最近恩恵に預かっているので作ってよかったなと思っています。
基本的に、where,select,reduce,groupBy,orderBy,join,zip,sum,averageが出来るようになっています。
詳細は、githubの以下のサイトを見てもらえばいいと思いますが、比較的速度を気にするようにしているので、中で処理するときのループ回数が少なくなるように設計してあります。
toVar()および、reduce()で配列が戻ってきます。
groupBy,orderBy,join,zip,sum,averageなどは、実際には一回実行して、新しくArrayWrapperでWrapしていますが、それ以外はできるだけ1回のループで処理が行われるようになっています。
ArrayWrapper for PHP
例えば、whereしてselectしてその結果を更に(意味ないけど)whereしたものを返すような書き方は以下のように出来ます。
(テストコードまんま貼り付けですが、$expectedが実行した結果だと思ってください。
$target = new ArrayWrapper(
array(
array("key" => 1,"value" => 10),
array("key" => 2,"value" => 11),
array("key" => 3,"value" => 12),
array("key" => 4,"value" => 13),
array("key" => 5,"value" => 14)
)
);
$actual = $target
->where(function($x){return $x["key"] > 2;})
->select(function($x){return array("K" => $x["key"],"V" => $x["value"] * 2);})
->where(function($x){return $x["K"] > 3;})
->toVar();
$expected = array(
array("K" => 4,"V" => 26),
array("K" => 5,"V" => 28)
);
例えば、groupByなんかは以下のように書けるようになっています。
$target = new ArrayWrapper(
array(
array("id" => 2,"value" => 10),
array("id" => 2,"value" => 11),
array("id" => 3,"value" => 12),
array("id" => 3,"value" => 13),
array("id" => 5,"value" => 14)
)
);
//toVarで配列に戻す。
$actual = $target
->groupBy(array("id"))
->toVar();
//で結果、こうなる
$expected = array(
array("keys" => array("id" => 2),"values" => array(
array("id" => 2,"value" => 10),
array("id" => 2,"value" => 11)
)),
array("keys" => array("id" => 3),"values" => array(
array("id" => 3,"value" => 12),
array("id" => 3,"value" => 13),
)),
array("keys" => array("id" => 5),"values" => array(
array("id" => 5,"value" => 14)
))
);
joinもこんなふうに書きます。
$leftArray = array(
array("key" => 2,"name" => "Nasal Hair Cutter"),
array("key" => 3,"name" => "scissors"),
array("key" => 5,"name" => "knife")
);
$rightArray = array(
array("id" => 1,"item_id" => 2,"value" => 10),
array("id" => 2,"item_id" => 2,"value" => 20),
array("id" => 3,"item_id" => 2,"value" => 30),
array("id" => 4,"item_id" => 3,"value" => 40),
array("id" => 5,"item_id" => 3,"value" => 50),
array("id" => 6,"item_id" => 5,"value" => 60),
array("id" => 7,"item_id" => 5,"value" => 70),
);
$target = new ArrayWrapper($leftArray);
$actual = $target
->join($rightArray,
array("key"),
array("item_id"),
function ($leftValue,$rightValue)
{
return
array("item_id" => $rightValue["item_id"],
"name" => $leftValue["name"],
"value" => $rightValue["value"]);
})
->toVar();
$expected = array(
array("item_id" => 2,"name" => "Nasal Hair Cutter","value" => 10),
array("item_id" => 2,"name" => "Nasal Hair Cutter","value" => 20),
array("item_id" => 2,"name" => "Nasal Hair Cutter","value" => 30),
array("item_id" => 3,"name" => "scissors","value" => 40),
array("item_id" => 3,"name" => "scissors","value" => 50),
array("item_id" => 5,"name" => "knife","value" => 60),
array("item_id" => 5,"name" => "knife","value" => 70),
);
実際に、業務で使っていますが、groupBy、sum,orderByあたりはかなり重宝しています。