「ラムダ式とLINQ」C# Advent Calendar 2011
http://atnd.org/events/21988クリスマス(12/25)を過ぎてるから、どうせ追加されないとネタで参加したら追加されてしまったので書きます。
自分でもLINQとかラムダ式の理解が曖昧だったのでラムダ式について、勉強のため書きます
これを元にしました。
◯ラムダ式
まず、
↓数学者が関数を定義するのにこう書くようです。
(x, y, z)→ x + y + z 引数 → 返り値
「引数」と「返り値」をマッピングしている。
これをC#に直すと、
↓こうなる
(x, y, z) => x+ y+ z;
数学者が書く「→」をC#では「=>」と示します。ちなみに「goes to」(ゴーズ・トゥ)と読む。
※「->」ではない
他の一部の言語の制約では、「ラムダ式中に”副作用”を起こしてはならない」があるそうですが、
C#ではは大丈夫。
ちなみにJavaScriptの「関数リテラル」もラムダ式と同じらしい
JSではこうなる
function f(x, y, z) {return x+ y+ z;}
LINQなどにも使用可能。
LINQはSQLっぽくかけるが、データベース以外にも使用可能。
列挙可能なオブジェクト(IEnumeratable
つまり、コレクションです。
コレクション・・IEnumerable インターフェイスを実装するクラス。普通の配列、List、Dictionaryなど。
まず、このようにファイル名を列挙するstaticメソッドを作成。
static GetAllFilesInDirectory<string> GetAllFilesInDIrectory(string directoryPath) { return Directory.EnumerateFiles(directoryPath, "*"), SearchOption.AllDirectories); }
→引数に「ディレクトリのパス」を指定し、検索パターン「*」に一致する(つまり、全て)
ファイルを列挙して返します。
http://msdn.microsoft.com/ja-jp/library/dd383571.aspx
using System.Linq; var bigfiles = from file in GetAllFilesInDirectory(@"C:\") // ここが探し元 where new FileInfo(file).Length > 10000000 // 1000万バイトより大きいファイルを(0は7つ) select file; // ファイルを取る
bigfilesはクエリ式を変数に割り当ててます。
whereは省略可!条件式を書く。
(疑問)なぜnew してる??
つまり、「C:\」中のすべての ファイルから1000万バイトより大きいファイルを取り出すってこと。
ちなみにこの段階では、"クエリを宣伝したのみ"で、実際に何も起こらない。
foreach (string file in bigfiles) { Console.WriteLine(file); }
→先ほどのプログラムに格納したbigfilesから列挙して出力する。
「カレンダーのイベントを表すクラス」を定義してみます。
class CalenderEvent { public string Title { get; set; } // タイトル public DateTimeOffset StartTime { get; set; } // 開始日時 public TimeSpan Duration { get; set; } // 期間 }
→それぞれのプロパティにゲッター、セッターをつけておきます。
ちなみに DateTimeOffset(UTC日時)、 TimeSpan (時間間隔)は構造体みたいです。
http://msdn.microsoft.com/ja-jp/library/system.timespan(v=vs.80).aspx
http://msdn.microsoft.com/ja-jp/library/system.datetimeoffset.aspx
先ほどのクラスのサンプルデータを作成します。
List<CalenderEvent> events = new List<CalenderEvent> { new CalenderEvent { Title = "アドベントカレンダー書く", StartTime = new DateTimeOffset(2012, 12, 27, 23, 00, 00, TimeSpan.Zero), Dration = TuneSpan(3) }, new CalenderEvent { Title = "正月", StartTime = new DateTimeOffset(2013, 1, 1, 12, 00, 00, TimeSpan.Zero), Dration = TuneSpan(2) } }
上のサンプルデータをLINQで並び替えてみます
var eventsByStartTime = from ev in events // 検索元 orderby ev.StartTime // 並び替え条件 select ev; // 選択
先ほどのeventsをStartTimeで昇順に並び替える。って意味です。
(疑問)evは仮名みたいなものですか?
ちなみに、orderbyは昇順がデフォルトです。
・↑の式と同等のことを、ラムダ式でこう書けます。
var eventsByStartTime = events.OrderBy(ev => ev.StartTime);
(疑問)
inの前にあったものが、「=>」の前?
「=>」のあとに、並び替え条件を記載?
なぜ、evって勝手に命名できる?
結局、理解が曖昧でしたがここまで。