万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

  • ・資産運用おすすめ
    10万円は1000円くらい利益
    資産運用ブログ アセマネ
    • ・寄付お願いします
      YENTEN:YYzNPzdsZWqr5THWAdMrKDj7GT8ietDc2W
      BitZenny:ZfpUbVya8MWQkjjGJMjA7P9pPkqaLnwPWH
      c0ban:8KG95GXdEquNpPW8xJAJf7nn5kbimQ5wj1
      Skycoin:KMqcn7x8REwwzMHPi9fV9fbNwdofYAWKRo

    ラムダ式LINQC# 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などにも使用可能。

    LINQSQLっぽくかけるが、データベース以外にも使用可能。
    列挙可能なオブジェクト(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って勝手に命名できる?

    結局、理解が曖昧でしたがここまで。


    唯一のC#デザパタ

    結城浩Javaデザパタ本のC#デザパタ移植

    http://gushwell.ldblog.jp/archives/50333227.html