PHPのGinqについて纏めました

PHPのGinqについて纏めました

SN

11/21 02:47



はじめに

初めまして、k.s.ロジャースの西谷です。

最近はPHPを中心に開発を進めております。

その中でGinqを採用しているプロジェクトがあり、以前から利用していたC#のLINQと同じことが出来るとのことでびっくりしています。

勉強をしていくなかで、LINQのよく使う構文をまとめた記事が非常に参考になったため、サンプル集としてGinqで書いていこうと思います。

C#の開発者からPHPに移行する方はあまり多くないと思いますが、少しでも手助けになればと思います。

間違い等があればコメントにてお知らせいただけたらと思います。


導入手順

詳しい導入手順は他記事にお任せします。

次のライブラリを導入すれば、Ginqを利用できるようになります。

https://github.com/akanehara/ginq


GinqやLINQの利点

GinqやLINQを利用することで、開発者としてすぐに受けられるメリットはシンプルに配列操作が出来ることであると思います。

collection操作を利用しない場合は代入のためだけにforeach回して、その結果煩雑なコードになることが多々あります。

foreachと比べると少しパフォーマンスが落ちてしまいますが、可読性・生産性が向上すると思います。

例えば、次のようなコードをGinqやLINQに切り替えるだけでも、読みやすくなると思います。

// 通常のループ
$data = [];
foreach($users as $key=>$value) {
if ($value["age"] > 20) {
$data[$key] = $value;
}
}

// Ginqを使う
$data = Ginq::from($users)->where(function ($v) {
return $v["age"] > 20;
});



// 通常ループ
var data = new List<User>();
foreach (var user in users)
{
if (user.age > 20)
{
data.Add(user);
}
}

// LINQを使う
var data = users.Where(v => v.age > 20);



基本的な操作

//0~9までの配列
$data = Ginq::Range(0, 9)->ToArray();

// 条件検索
// [0, 2, 4, 6, 8]
$evens = Ginq::from($data)->where(function ($i) {
return $i % 2 == 0;
})->toList();

// 配列内の全てに対して処理を行う
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
$aquares = Ginq::from($data)->select(function ($i) {
return $i * $i;
})->toList();

// 先頭からn個取得
// [0, 1, 2]
$oneTwoThree = Ginq::from($data)->take(3)->toList();

// n個スキップして残りを取得
// [7, 8, 9]
$sevenEightNine = Ginq::from($data)->drop(7)->toList();
$result[] = $sevenEightNine;

// 先頭から条件を満たさなくなるまでとる(Whereとは一度でも条件を満たさなくなったらストップする点でちがう)
// [0, 1, 2, 3]
$while4 = Ginq::from($data)->takeWhile(function ($i) {
return ($i + 1) % 5 != 0;
})->toList();

// 条件を満たしている間スキップして残りをとる
// [4, 5, 6, 7, 8, 9]
$skip4 = Ginq::from($data)->dropWhile(function ($i) {
return ($i + 1) % 5 != 0;
})->toList();

// 先頭を取得する
// 0
$first = Ginq::from($data)->first();

// 条件を満たす最初の要素を取得する(ない場合は例外)
// 1
$firstOdds = Ginq::from($data)->first(function ($i) {
return $i % 2 == 1;
});

// 条件をみたすものがないときは先頭を返す
// 0
$default0 = Ginq::from($data)->firstOrElse(function ($i) {
return $i < -10;
});

// 最後を取得する
// 9
$last = Ginq::from($data)->last();

// 条件を満たす最後の要素を取得する
// 8
$lastEven = Ginq::from($data)->last(function ($i) {
return $i % 2 == 0;
});



配列の生成

// 0~9の配列
$data = Ginq::Range(0, 9);

// 同じ値の配列を作成
// [4, 4, 4, 4, 4]
$repeat = Ginq::repeat(4, 5)->toList();

// 空の配列を返す
// []
$empty = Ginq::zero()->toList();

// [0, 1, 2, 3, 4]
$data = Ginq::range(0, 4)->toList();
// [0, 1, 4, 9, 16]
$square = Ginq::from($data)->select(function ($i) {
return $i * $i;
});

// 2つの配列を繋げる
// [0, 1, 2, 3, 4, 0, 1, 4, 9, 16]
$concat = Ginq::from($data)->concat($square)->toList();

// 2つの配列を合成する
// ["0 with 0", "1 with 1", "2 with 4", "3 with 9", "4 with 16"]
$zip = Ginq::from($data)->zip($square, function ($d, $s) {
return "$d with $s";
})->toList();

// join用のデータを用意する
$join_data = Ginq::from($data)->select(function ($d) {
return ["id" => $d, "square_" => $d * $d];
})->toList();
$join_square = Ginq::from($square)->select(function ($s) {
return ["id" => $s, "dummy" => "dummy-{$s}"];
})->toList();

// 2つの配列の結合
// join(結合先の配列, 結合元のkey, 結合先のkey, function)
// [["id" => 0, "dummy-0"], ["id" => 1, "dummy-1"] ...]
$join = Ginq::from($join_data)->join($join_square, "[square_key]", "[id]", function ($join_data, $join_square, $data_key, $square_key) {
return [
"id" => $join_data["id"],
"dummy" => $join_square["dummy"]
];
})->toList();



数学関連

// 0~9
$data = Ginq::Range(0, 9);

// 最大値
// 9
$max = Ginq::from($data)->max();

// 関数適用した後の最大値
// 81
$max2 = Ginq::from($data)->max(function ($i) {
return $i * $i;
});

// 最小値
// 0
$min = Ginq::from($data)->min();

// 関数適用した後の最小値
// 5
$min2 = Ginq::from($data)->Min(function ($i) {
return i + 5;
});

// 和集合
// 0,1,2,3,4,9,16
$union = Ginq::from($data)->union($square)->toList();

// 積集合
// 0,1,4
$intersect = Ginq::from($data)->intersect($square)->toList();

// 差集合
// 2,3
$except = Ginq::from($data)->except($square)->toList();

// 排他的論理和
// 2,3,9,16
$xor = Ginq::from($union)->except($intersect)->toList();



参考記事

以下の記事を参考、引用させて頂きました。

https://qiita.com/Marimoiro/items/0e119b47d65bf138789a

https://qiita.com/hidenorigoto/items/bee60836112e49eccadb


終わりに

今回はGinqについてご紹介させて頂きました。

非常に便利な機能だと思いますので、利用プロジェクトが増えればと思います。


Wantedlyでもブログ投稿してます

Techブログに加えて会社ブログなどもやっているので、気になった方はぜひ覗いてみてください。

https://www.wantedly.com/companies/ks-rogers

PR:デジカフェ

Qiita - PHPタグが付けられた新着投稿

macOS MojaveでLiip PHPのインストール

SN

12/17 17:33



はじめに

php.netのMac OS X へのインストール > バンドルされている PHP の使用法でも紹介されているLiipのPHPは、macOS MojaveではそれまでのmacOSと違って、OSX標準のapacheにインストールできなくなり...

Laravel Socialiteの InvalidStateException エラー解決方法

SN

12/17 17:16



事象

Socialiteを使ってソーシャルログインを実装したのだが、callback URLをリクエストする際にエラー発生。

厄介なのは認証する人のSNS側のパーミッション設定(ブラウザ?)によってエラーになったりな...

PHPUnitでassert()がコケることをテストする

SN

12/17 16:57



やりたいこと

PHP7.1、PHPUnit 7.2で

class Foo {
public static function bar(string $a){
assert($a === "po");
echo $a;
}
}




class FooTest extends TestCase{
/**
* @test
*/
...

PHP Conference 2018に参加してわからなかったことまとめ

SN

12/17 16:53



この記事について

2018年12月15日に大田区産業プラザで行われたPHP Conference 2018に参加しました。

その際に「気になったことや理解できなかったこと」と「それが何なのかを後で調べた結果」を纏めた個...

PhpStormからLaradockのテストを実行する

PhpStormからLaradockのテストを実行する

SN

12/17 16:38



経緯

PHPカンファレンス2018でLaravelでTDDを体験しよう #phpcon2018がとても良くて、LaravelでTDDをしたいと思った。

(特にPhpStormからCommand + rで都度テスト実行をしたいと思った。)

TDDはリズム...

ディレクトリ内のファイルの消去

SN

12/17 16:34



ファイルパスの条件を指定

array_map('unlink', glob("path/to/dir/*.php"));



ディレクトリも含めて消去

foreach (new \RecursiveDirectoryIterator('path/to/dir', \FilesystemIterator::SKIP_DOTS) as $...

cakephp2のインストールはcomposer.jsonにphpのバージョンを明記

SN

12/17 15:55

以前こちらの記事に書いたcakephp2の始め方だが、

https://qiita.com/uedatakeshi/items/08d5c577e07489c4d9f9

いざやってみると最新のcakephp2だと依存関係でphp5.3に対応していないようなライブラリが入って...

【Laravel5.7】Email Verificationの使い方

【Laravel5.7】Email Verificationの使い方

SN

12/17 15:54



Email Verificationの機能


メールアドレスとパスワード(+α)を入力してもらう
入力されたメールアドレスに仮登録のメールを送信
仮登録に書かれたURLにアクセスすると本登録が完了


最近よくあるユーザ登録...

WordPress Gutenberg の真価

WordPress Gutenberg の真価

SN

12/17 15:34

ついに、WordPress 5.0 がリリースされました!

実際に使用した感触も踏まえ、Gutenbergについて少し書かせて頂きたいと思います。


Gutenbergとは

WordPress 5.0 に搭載されたビジュアルエディターです。<...

Laravel5の複数ルーティングファイル作成時の順番について

SN

12/17 15:29



はじめに

Laravel5.3からRouteServiceProvider.phpを拡張すると、複数ファイルでルーティングを管理出来るようになりました。

例えば以下のように分けることができます。


一般用ルーティング(web.php)
...

MAMPを使ってのCakePHP環境構築備忘録

SN

12/17 15:13



前提として

・MAMP導入済み

・もしかすると違うかも(素人なんで)


第一ステップ

・PHPバージョン変更

参考

MAMPとComposerを使ったCakePHP3.xのローカル開発環境の構築

メモ:初心者とし...

Welcartのカートで消費税と税込価格を出す

Welcartのカートで消費税と税込価格を出す

SN

12/17 14:22



こんな感じにwelcartで価格を出す。

wc_cart_page.phpの</tfoot>の直前にコードを足します。

(私はクーポンプラグインなど使っていませんので諸々アレンジしてください。)


wc_cart_page.php
...

月数100万アクセスをDB使わず超簡単にさばく

SN

12/17 13:37

初Qiitaな個人開発者のひさしAppと申します @Hisashi_vc

最近「じぶんコイン」というコイン系SNSサービスを作り、月間100万~数百万アクセスを激安サーバー(1000円ちょい)でさばき中です。

じぶんコイン

...

PHPで簡単な自動販売機作ってみた!!!

SN

12/17 13:08

まずは投入金額と飲みたいドリンクを定義する!


vending_machine.php
$money = 150;
$drink = '缶コーヒー';



swich文を使ってドリンクの値段を定義する!


vending_machine.php
switch ($drink){

// $...

PHP URL分ける GETパラメーター

SN

12/17 11:58



PHP URL分離

クエリ以前(?以前)のURLが欲しかったのでメモします。


url.php
$url = 'http://www.example.com/hoge.html?param1=foo&param2=bar';
$sample_url = parse_url($url);
var_dump($sample_url)...

PHP Conference 2018に参加してわからなかったことまとめ

SN

12/17 11:51



この記事について

2018年12月15日に大田区産業プラザで行われたPHP Conference 2018に参加しました。

その際に「気になったことや理解できなかったこと」と「それが何なのかを後で調べた結果」を纏めた個...

Progate「PHP.Ⅱ」の学習をまとめてみた

SN

12/17 11:22



はじめに

PHPの理解がほとんど進まず、先週の目標を達成できませんでした。

原因は二つ考えられます。

「情報源の検索に時間がかかりすぎている」

「アウトプット不足」

の二つです。

こ...

正規表現がわからないから見たいリンク集

SN

12/17 11:02



PHP


PHP
/w : [a-zA-Z0-9_]
/d : [0-9]
xパターン修飾子 : フリーフォーマットモードを有効にする。ASCIIの空白文字しか認識せずUnicodeに含まれる他の空白文字は認識しない





Webツール


preg_matchとpr...

PHPカンファレンス2018に行ってきました

PHPカンファレンス2018に行ってきました

SN

12/17 10:56



はじめに

この記事はPHP Advent Calendar 2018の14日目の記事です。

空いてたので埋めます。

PHPカンファレンス2018に行ってきたので感想などを書こうかなと思います(開催が12/15なのに12/14のアドカ...

laravel-form-builder のすすめ

laravel-form-builder のすすめ

SN

12/17 10:13

Laravel Advent Calendar 2018 - Qiita の17日目の記事です。

福岡のフリーランスエンジニアです

今年はLaravel触ることが多いのでLaravelのことを書きます

去年まではSymfonyの記事を書いていた気がす...

PR:Amazonプライムビデオ

Qiita

Qiita - 人気の投稿

Qiita - AWSタグが付けられた新着投稿

Qiita - Gitタグが付けられた新着投稿

Qiita - Linuxタグが付けられた新着投稿

Qiita - MySQLタグが付けられた新着投稿

Qiita - nginxタグが付けられた新着投稿

Qiita - Dockerタグが付けられた新着投稿

Qiita - Pythonタグが付けられた新着投稿

Qiita - Rubyタグが付けられた新着投稿

Qiita - PHPタグが付けられた新着投稿

Qiita - Javaタグが付けられた新着投稿

Qiita - JavaScriptタグが付けられた新着投稿