調べども、「便利だ」「こう使え」ってばかりで、
なにをするものか、理解に苦しんだので、簡単にまとめてみたい。
なにができるの?
LINQ
(1). 1つ以上のリストから1つのリストを再構成する ※ここでLINQを使う
(2). 再構成したリストを処理する
ラムダ式
「引数 => どうする?」という書式
関数の設定が必要なとき、関数と引数をひも付けて設定できる
いきなり サンプル
// 文字の配列をスペースで前後に分けて、手前がAのものだけコンソールに出力する
string[] list_src = { "A A-1", "A A-2", "B B-1", "A A-100", "C C-9999" };
var list_dest = list_src.Where( p1 => IsA(p1) ); // (1)とラムダ式
// 以下(2)
foreach (string s in list_dest)
{
Console.WriteLine(s);
}
bool IsA(string p)
{
return p.Split(' ')[0] == "A";
}
A A-1
A A-2
A A-100
ラムダ式をさわってからLINQを見たほうがいいのだけど、私は順序を間違えてラムダ式の含まれたLINQのサンプルに出会って困惑しました。
上のサンプルもそうだが、ラムダ式から見ていったほうがいい。
ラムダ式の概要
「関数の設定が必要なとき、関数と引数をひも付けて設定できる」
を、細かく見ていく。
「関数の設定が必要なとき」は...
- ボタンが押されたとき
- テキストボックスの内容が変更されたとき
- ソートなどで手作りの比較関数が必要なとき
- LINQでリストの再構成の関数が必要なとき
「関数の設定が必要なとき」を自前で作ることもできる。
そういったときに、引数 => どうする?、という形で書くことができる。
p1 => IsA(p1)
この場合
p1という引数が呼ばれるから
IsA関数の1つめの引数にp1をわたしてくれ
となる。
前半について
「関数の設定が必要なとき」に使うものだから、つまり、予め決まっている引数があり、それをp1である、という事を示している。
引数が複数の場合
(p1, p2) => IsA(p1,p2)
このように、引数の複数にしたり、直接中身を書き始めると、どんどんオバケみたいになるものの、「引数の明示 => どうする?」と見分けるのが重要らしい。
LINQ そもそもいらない?
リストの要素を再構成(抽出)するときに、処理を書いてしまえばいいのではないか?
string[] list_src = { "A A-1", "A A-2", "B B-1", "A A-100", "C C-9999" };
foreach( string s in list_src )
{
string[] splitS = s.Split(' ');
if (splitS[0] == "A" )
{
Console.WriteLine(splitS[1]);
}
}
処理速度やぱっとみで、この方が理解しやすそうだ。
いったん別にリストを構成するなんて無駄に思える?
リストの再構成(抽出)が複雑になるほど、
その結果で行うことが複雑になるほどほど、
foreachの中身は混沌としていく。
だから、役割分担をし、コードを分離する。
ここが分かっていないと、複雑になってないか?とメリットがみいだせない。
実際、サンプルを比較すると、
LINQを使わないほうが読みやすい。
それは、全体が小さく、順をおって処理が読めるから。
すこしサンプルの説明をしておくと、
var list_dest = list_src.Where( p1 => IsA(p1) ); // (1)とラムダ式
ここでは、list_destというリストを新しく構成宣言している。
その実際に使うとき、list_srcの中から欲しいものを探してくる。
~.Where( boolが戻り値の関数 );
で、欲しいものを探してくれて、関数は、ラムダ式で設定している。
※「実際に使うとき」というのは foreach (string s in list_dest)
LINQは、foreachが使えるなら配列でも可能で、
Where以外にもいろいろあるみたい。
ひとりごと
実はLINQについて最初勘違いしてまして、
「リストを検索して条件判断して、処理までできるんじゃないか」と。
良い記事・ページに当たらなかっただけかもしれませんが...