こんにちは、Mottyです。
久々の投稿となりますが、今回はC#のLINQについてまとめてみました。
概要
LINQは総合言語クエリ(Language Integrated Query)の略称で、C#言語に直接クエリ機能を統合した言語です。LINQを使用すると、ソースから必要なデータをクエリしたり抽出したり…といったことを最小限のコーディングで実行できます。
なぜ統合なのかというと、様々な種類のデータ集合(ListやCollection,SQLデータベース、XML,JSONデータなど)に対して標準化された方法でデータに問い合わせることができるからということです。
C#においてデータの操作というと、ほぼほぼLINQ構文によるものになるので、覚えておいて損はないだろうと思います。
LINQ構文の種類
LINQの書き方には主に2種類あります。SQL文風のクエリ構文と、ドットで命令をつないでいくメソッド構文です。下記それぞれ比較してみましょう。
クエリ構文
varlist=newList<int>{1,51,64,2,23,24};//クエリ構文varquery=fromx//from句のものは何でもいい、仮にxとおくinlist//抽出したいListwherex%2==0// 抽出条件orderbyx//並べ替えselectx;//最後はSelect句で締めるforeach(varliinquery){Console.WriteLine(li);}Console.Readkey();//output//2//24//64
メソッド構文
varmethod=list.Where(x=>x%2==0).OrderBy(x=>x)foreach(varliinmethod){Console.WriteLine(li);}Console.Readkey();//output//2//24//64
比べてみるとわかるように、クエリ構文のほうがやや冗長になります。
また一部メソッド構文でしか使えない操作があり、紹介内容はメソッド構文に統一したいと思います。
構文例
要素の抽出
LINQでは条件を指定すると抽出できる構文が用意されています。
FirstOrDefault()
単一の要素を取得するメソッド。該当する要素のはじめ(First)を取得、該当しない(Default)場合はnullが返ってくる。
varlist311=newList<int>{1,2,3,4,5,6,7,8,9,10};varquery311=list311.FirstOrDefault();Console.WriteLine(query311); //output : 1Console.ReadKey();
引数にラムダ式を指定することで条件を指定することが可能。
varlist311=newList<int>{1,2,3,4,5,6,7,8,9,10};varquery311=list311.FirstOrDefault(x=>x>=5);//5以上のものConsole.WriteLine(query311); //output : 5Console.ReadKey();
条件に合致しない場合、規定値である0が返ってくる。
varlist311=newList<int>{1,2,3,4,5,6,7,8,9,10};varquery311=list311.FirstOrDefault(x=>x>100);//100以上のものConsole.WriteLine(query311); //output : 0Console.ReadKey();
文字列に対してのクエリ、見つからない場合はnullが返る。
varlist311=newList<string>{"Osaka","Hokkaido","Tokyo","Fukuoka"};varquery311=list311.FirstOrDefault(x=>x=="Kanagawa");Console.WriteLine(query311);// (null)Console.ReadKey();
First
こちらも単一の要素を取得するメソッド。指定の要素が見つかればFirstOrDefaultと変わらないが見つからなかった場合、例外がthrowされる。
try{varlist312=newList<string>{"Osaka","Hokkaido","Tokyo","Fukuoka"};varquery312=list312.First(x=>x=="Nagoya");Console.WriteLine(query312);}catch(Exceptione){Console.WriteLine(e.Message); //output:シーケンスに一致する要素は含まれていません。}finally{Console.ReadKey();}
LastOrDefault
該当する要素の最後を取得する。
varlist=newList<int>{50,60,70,80,90};Console.WriteLine(list.LastOrDefault(x=>x>70));//output: 90Console.ReadKey();
SingleOrDefault
SingleOrDefault。文字通り要素数が単一であった場合に、その要素を返す。
合致しない場合は少しややこしい。複数あった場合は例外がスローされ、ひとつもなかった場合は規定値である0を返す。
varlist=newList<int>{50,60,70,70,80,90};Console.WriteLine(list.SingleOrDefault(x=>x==70));//Error:シーケンスに複数の要素が含まれています。Console.WriteLine(list.SingleOrDefault(x=>x==80));//output:80Console.WriteLine(list.SingleOrDefault(x=>x==0));//output:0Console.ReadKey();
単一の取得に関して表に示すと、以下のようになる。
メソッド | 要素が複数見つかった場合 | 要素が一つだけ見つかった場合 | 要素が見つからなかった場合 |
---|---|---|---|
FirstOrDefault() | はじめの要素 | はじめの要素 | 0もしくはnull |
First() | はじめの要素 | はじめの要素 | 例外がスローされる |
LastOrDefault() | 末尾の要素 | 末尾の要素 | 0もしくはnull |
Last() | 末尾の要素 | 末尾の要素 | 例外がスローされる |
SingleOrDefault() | 例外がスローされる | 該当した要素 | 0もしくはnull |
Single() | 例外がスローされる | 該当した要素 | 例外がスローされる |
まとめ
LINQは構文としては簡単ですが、データを扱う場合はほぼかならず使う手法なので、何回も書いて覚えて損はないと思います。
次回もLINQシリーズを書こうと思っております。
参考
・Microsoft.Docs LINQ
https://docs.microsoft.com/ja-jp/dotnet/standard/linq/
・地平線に行く(LINQ構文を網羅)
https://yujisoftware.hatenablog.com/entry/20111031/1320068429
・陰干し中のゲーム開発メモ(SingleOrDefaultについての解説)
https://www.urablog.xyz/entry/2018/05/31/070000