2019/11/2(土) kosen-fun勉強会 で発表。 ↓Connpass↓ https://kosen-fun.connpass.com/event/150752/
LINQの魅力C#を制している者はLINQを制しているSpeaker:@AtriaSoft2019/11/2(土) kosen-fun勉強会
View Slide
About me.@AtriaSofthttp://atriasoft.work/Atria64• 畑 大地(a.k.a. Atria)• 公立はこだて未来大学B1• C#/C++を触ってます• 競技プログラミングが趣味• 最近はXamarin.AndroidとAzure Functionsを用いたALLC#開発にハマっています
LINQへの導入LINQについて知るために
こういう時どうする?• データ集合が与えられる– 名前と年齢が格納されている• 年齢順に並び替えたデータ集合にしたい• 未成年(20歳以下)は省きたい• どう実装するのが最適か
C#でのLINQを用いない実装• for文を回して挿入ソートまがいなことをしてみる• 冗長なコード• 実装が難しい• Dictionaryは楽だから使ってます実例(C#)
冗長、面倒、汚い
LINQの実装
シンプル、便利、きれい
すげぇだろ?
~僕からのメッセージ~LINQを使いましょう
LINQ(総合言語クエリ)とは• 様々な種類のデータ集合に対して標準化された方法でデータを問い合わせる事を可能にする。これでは難しい…• データ集合の扱いを超便利にする!!比較的簡単!
クエリ式と標準クエリ演算子LINQの記法の話
クエリ式と標準クエリ演算子(1)• クエリ式– SQLのような “問い合わせ言語風” の文法で記述する。– あんまりこの文法は見ない• 後述の “標準クエリ演算子” の方がメジャーvar hoge =from score in scoreswhere score > 80orderby score descendingselect score;やってること(だいたいこんな感じ)• scoresのデータ集合から• Scoreが80以上の• 降順な• Scoreの配列を生成する
クエリ式と標準クエリ演算子(2)• 標準クエリ演算子– LINQパターンを形成する ”メソッド”– 一般に広く使われる– 今回はこちらの記法で紹介していくvar hoge = score.Where(x => x > 80).OrderByDescending(x => x);やっていることは前の式と一緒。
クエリ式と標準クエリ演算子(3)
ラムダ式LINQの力を引き出すために
切っては切れないラムダ式(1)• 今まで(値ベースの考え方)– メソッドに値を渡す• ラムダ式(関数型志向の考え方)– 急にメソッド(処理)を渡すC#はマルチパラダイム言語。様々な考え方が混在する分、初心者にとって複雑。F#,Haskell,LISP,Scalaなど
• (x => x)のような式のカタチをしている• ここで出てくる “=>” はラムダ宣言演算子と呼ばれる• 例えば (x => x )であれば– Xには各要素が与えられていて– その各要素xに操作を行う…みたいな• 正直な所説明が難しい• 使っていくうちで慣れていくものだと思う切っては切れないラムダ式(2)
LINQの代表的な機能LINQを実際に使うために
昇順、降順ソートOrderBy()• OrderBy()を用いると昇順ソートできる。• 降順ソートはOrderByDescending()
競プロ御用達Split()• 文字列を解析して分けてくれる• CSVファイルの解析によく使う• 競プロの要素受け取りでよく使う上のソースコードの動き → int[] hoge = {1,1331,303};
データ形式を揃えるSelect()• コレクションの値を一括して変換する場面で活躍• 上の例ではすべての要素をint型にキャストしている• いわゆる”射影”もできる• できること例– すべての要素を二倍する– すべての要素をStringに変換する
配列やListに変換 ToList(),ToArray()• 配列やList型に変換できる。便利。• 基本的にLINQ演算の結果は” IEnumerable型”– ToList()やToArray()などに頼る場面が多い– IEnumerableには、今回深く触れない
組み合わせた例の実行結果きれいに記述することができた
条件に合う個数を調べるCount()• データ集合に何個要素が含まれているのかを返す• “条件を満たす要素が何個あるのか”みたいなのも取れる(後で詳しく)• Java系では ”配列.length” などで取れるやつ• C++では確か ”sizeof(配列)”• 計算量はO(n)っぽい。– 速度を必要とする現場(競プロなど)では気をつけること
Conut()を使った図• 先程より、int[] hoge = {2,1331,303}である• Count()を用いることで要素数を取得している
条件に合うデータにするWhere()• 条件に合う要素を取り出し、新しく作り直す• 計算量はO(n),Count同様,注意すること偶数のみ取り出すコード
WhereとCount(1)• Countは“条件を満たす要素が何個あるのか” が取れる偶数のみ取り出したときの個数を返すコード
WhereとCount(2)• なので、わざわざWhereとCountを組み合わせる必要はない計算量にも全く変化がなかった(自分調べ)
WhereとCount(3)冗長なだけで全く意味がない。このようなコードは書かないようにしよう。
最大,最小,平均,合計Max(),Min(),Average(),Sum()• 説明不要?• 配列の最大最小平均合計を出してくれます• なかなかに便利です
遅延評価LINQをより深く理解するために上級編
ちょっと難しい遅延評価• 遅延評価は“必要な時に必要な値を参照する”というもの– 値が必要になるまで、値の評価を後回しにするというもの• 突き詰めるとモナドなどにたどり着くらしい。こわい。• 説明が難しいので素晴らしい記事を紹介しておわります
遅延評価についての素晴らしい記事• [雑記] LINQ と遅延評価 - C# によるプログラミング入門 ... - ++C++– https://ufcpp.net/study/csharp/sp3_lazylist.html• 【小ネタ】LINQの「遅延評価」「即時評価」って何が違うの? - Qiita– https://qiita.com/4_mio_11/items/dec20929f189bb2b1a8e
まとめLINQってめっちゃいいでしょ
LINQはC#だけのものではなくなった• C#LINQに人々は刺激され、LINQは様々なプログラミング言語へ広まった• 例– Python -> pynq– PHP -> PHPLinq– JavaScript -> jLinq, JSINQ ほか– Go -> go-linq• あなたの主用言語でも使えるかもしれない
Let’s LINQ