Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/akanehara/ginq

`LINQ to Object` inspired DSL for PHP
https://github.com/akanehara/ginq

Last synced: about 1 month ago
JSON representation

`LINQ to Object` inspired DSL for PHP

Awesome Lists containing this project

README

        

# Ginq

### PHPの配列操作に幸せを!

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

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

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

## 使い方

```php
require_once('Ginq.php');
```

**Ginq**をインポートします。

```php
$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** を駆動して結果を得るために、`foreach`で **Ginq** を反復してみます。

```php
foreach ($xs in $x) { echo "$x "; }
```

```
1 9 25 49 81
```

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

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

```php
$xs->toList();
```

```
array(1,9,25,49,81);
```

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

## セレクタと述語

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

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

### 述語

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

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

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

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

### セレクタ

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

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

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

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

### 結合セレクタ

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

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

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

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

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

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

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

foreach ($xs in $x) { echo "$x\n"; }
```

```
お肉にタイム!
パスタにバジル!
サラダにティル!
```

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

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

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

は、

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

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

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

## もっと複雑な例

## リファレンス