Skip to content

Latest commit

 

History

History
142 lines (91 loc) · 4.85 KB

README.ja.md

File metadata and controls

142 lines (91 loc) · 4.85 KB

Ginq

PHPの配列操作に幸せを!

Ginq はPHPの配列やイテレータを統一的に(そのうえ楽しく!)操作するための DSL です。

GinqLINQ to Object にインスパイアされましたが、クローンではありません。PHPの配列やイテレータの事情にできるだけ寄り添ってデザインされています。

Ginq の多くの機能は、その結果を実際に取り出すまで処理を実行しません。この 遅延実行 という性質は、さまざまなメリットをもたらしてくれます。

使い方

require_once('Ginq.php');

Ginqをインポートします。

$xs = Ginq::from(array(1,2,3,4,5,6,7,8,9,10))
        ->where(function($x) { return $x % 2 != 0; })
        ->select(function($x) { return $x * $x; })
        ;

Ginqにデータを渡して、クエリを組み立てます。 ここでは配列から偶数の要素だけを抽出して、されにそれを2乗しています。

この段階ではまだ Ginq は何もしません。 「必要な結果は、元の配列を選択(where)・射影(select)したものである」 、ということをGinqに伝えただけです。

実際に Ginq を駆動して結果を得るために、foreachGinq を反復してみます。

foreach ($xs in $x) { echo "$x "; }
1 9 25 49 81

欲しい結果が得られました!

今度はtoList()を使って配列を得ましょう。

$xs->toList();
array(1,9,25,49,81);

Ginq には、ここで紹介した select()where() 以外にも、join() orderBy() groupBy() のような、SQLでお馴染みの機能も備わっています。

セレクタと述語

Ginq のほとんどのメソッドは、引数にクロージャをとります。

クロージャと聞くと、使いなれない人はちょっと怯んでしまうかもしれませんが、実のところまったく難しくありません。Ginqが要求するクロージャのほとんどは 「述語」 「セレクタ」 「結合セレクタ」 のたったの3種類に分けられ、すぐに覚えられます!

述語

where() のような 選択 を行うメソッドに渡すクロージャを、述語(predicate)いいます。述語は要素のキーと値のペアをとり、条件を満たすかどうかを真理値で返す次のようなクロージャです。

function ($v, [$k]) { return $v % 2 == 0; }

このクロージャをwhere()に渡すと、クロージャの結果がTrueとなるような要素、つまり偶数だけを選んで返してくれます。

もしもキーに関心がないなら、第2引数を省略しても問題ありません。

セレクタ

select() のような 射影 を行うメソッドに渡す関数を、セレクタ といいます。セレクタは要素のキーと値をのペアをとり、そこから新しい値(場面によってはキー)を作って返します。

function ($v, [$k]) { return $v * $v ; }

このクロージャをselect()に渡すと、元の要素の値を2乗した並びが得られます。

また、射影という基本的な用途以外にも、groupBy()ではグループ化のキーを、orderBy()では並び替えのキーを指定するために使われます。

結合セレクタ

結合セレクタ は左右2つの要素を1つにまとめるセレクタの一種で、join()zip() などで使われます。

function ($v0, $v1, [$k0, $k1]) { return array($v0, $v1) ; }

左右2つの値と左右2つのキー、合計4つの引数をとり、それを使って新しい値(あるいはキー)を作って返します。

もちろん、関心のない引数は省略しても大丈夫ですよ;-)

さて、2つの並びを要素ごとに綴じ合わせる、zip()の例を見てみましょう。

$foods  = array("お肉", "パスタ", "サラダ");
$spices = array("タイム", "バジル", "ディル");

$xs = Ginq::from($foods)
        ->zip($spices, function($f, $s) {
            return "$f$s";
        })
        ;

foreach ($xs in $x) { echo "$x\n"; }
お肉にタイム!
パスタにバジル!
サラダにティル!

セレクタのショートカット

セレクタ にかぎり、クロージャのかわりに文字列を渡すことができます。

Ginq::from($xs)->select('[key].property');

は、

Ginq::from($xs)->select(
    function ($v, $k) { return $v['key']->property; }
);

と同じ意味をもちます。 これはSymfonyのプロパディアクセスの記法に準じます。

http://symfony.com/doc/current/components/property_access/index.html

もっと複雑な例

リファレンス