Henehefu 用 ウィキ

メニュー



- Views

最近の更新

取得中です。

CSharp > Linq


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。


LINQメモ

定期的に記憶領域が破壊される脳ミソのためのページ

LINQ について

SQLのような関数型言語のようなC#でつかえる うひょーい な物

参考サイト


クエリ構文

サンプルコードはコンパイルチェックしてないので
エラーが出たら適当に直すこと

標準形(ふつー)

   var query =
       from item in list
       select item;

これって何か意味あるの?と思う使用例
   foreach(var item in query){
       Console.WriteLine(item);
   }

フレンドリスト内のフレの名前を選択する
   var query =
       from フレ in フレンドリスト
       select フレ.名前;

フレンドリスト内のフレの名前を大文字にして選択する
   var query =
       from フレ in フレンドリスト
       select フレ.名前.ToUpper();


フィルタリング(絞込み、抽出)

フレンドリストの中から糞樽以外のフレを抽出
   var query =
       from フレ in フレンドリスト
       where フレ.属性 != 糞樽 
       select フレ;

フレンドリストの中から18歳未満の女性を抽出する
   var query =
       from フレ in フレンドリスト
       where フレ.性別 == リア♀ && フレ.年齢 < 18
       select フレ;

並べ替え(ソート)

フレンドリストを名前でソートする
   var query =
       from フレ in フレンドリスト
       order by フレ.名前
       select フレ;

フレンドリストを名前を逆順でソートする
   var query =
       from フレ in フレンドリスト
       order by フレ.名前 desc
       select フレ;

グルーピング(グループ化)

フレンドリストを名前の頭文字でグルーピングする
   var query =
       from フレ in フレンドリスト
       group フレ by フレ.名前[0];

使用例
   foreach(var group in query){
       Console.WriteLine(group.Key);
       foreach(var item in group){
           Console.WriteLine("\t" + item.名前)
       }
   }

フレンドリストを名前の頭文字でグルーピングして、頭文字でソートする
   var query =
       from フレ in フレンドリスト
       group フレ by フレ.名前[0] into g
       order by g.Key
       select g;

フレンドリストを名前の頭文字でグルーピングして、それぞれの頭文字に何人いるか数える
   var query =
       from フレ in フレンドリスト
       group フレ by フレ.名前[0] into g
       select new {頭文字 = g.Key, 人数 = g.Count()};

結合

自分のフレと田中のフレから共通のフレを抽出する
   var query =
       from フレ in フレンドリスト
       from 田中のフレ in 田中.フレンドリスト
       where フレ == 田中のフレ
       select フレ;

自分のフレと田中のフレから共通のフレを抽出する(join版)
   var query =
       from フレ in フレンドリスト
       join 田中のフレ in 田中.フレンドリスト
       on フレ equals 田中のフレ
       select フレ;

中間値(let)

   // 例えば↓の例だと時間のかかる処理が2度走ってしまう
   var query =
       from フレ in フレンドリスト
       order by フレ.レリック作成().名前
       select フレ.レリック作成();

   // letを使って一時的に値を受け取って時間のかかる処理を1度だけにする
   var query =
       from フレ in フレンドリスト
       let 武器 = フレ.レリック作成()
       order by 武器.名前
       select 武器;


メソッド構文

Select

各要素を変換する。
テキストファイルを読み込んでそのまま出力
   var lines = File.ReadAllLines(@"hoge.txt");
   var query = lines.Select(line => line);

   foreach(var line in query){
       Console.WriteLine(line);
   }

テキストファイルを読み込んで大文字にして出力
   var lines = File.ReadAllLines(@"hoge.txt");
   var query = lines.Select(line => line.ToUpper());

   foreach(var line in query){
       Console.WriteLine(line);
   }

Select(インデックス付きなんだよ)

第2引数を持つ関数を渡すとインデックス番号がつく
テキストファイルを読み込んで行番号をつけて出力
   var lines = File.ReadAllLines(@"hoge.txt");
   var query = lines.Select((line, n) => new {Text = line, Num = n});

   foreach(var line in query){
       Console.WriteLine("{0}:{a}", line.Num, line.Text);
   }

Where

テキストファイルを読み込んで"hoge"を含む行を出力
   var lines = File.ReadAllLines(@"hoge.txt");
   var query = lines.Where(line => line.Contains("hoge"));

   foreach(var line in query){
       Console.WriteLine(line);
   }

劣化grep
 void 劣化Grep(string pattern, string path)
 {
   var regex = new Regex(pattern);
   var lines = File.ReadAllLines(path);
   var query = lines.Where(line => regex.IsMatch(line))
                    .Select((line, n) => new {Text = line, Num = n});

   foreach(var line in query){
       Console.WriteLine("{0}:{1}", line.Num, line.Text);
   }
 }

偶数を抽出
   int[] numbers = {0, 1, 2, 3, 4, 5};
   var query = numbers.Where(n => (n % 2) == 0);

   foreach(var n in query){
       Console.WriteLine(n);
   }

Aggregate

シーケンスを一つの結果にまとめる
string.joinもどき
   // string.Join(", ", words)と大体同じ
   var text = words.Aggregate((txt, word) => txt + ", " + word);

合計
   // numbers.Sum()もどき
   var 合計 = numbers.Aggregate((s, n) => s + n);

すべての要素をかける
   var 結果 = numbers.Aggregate((s, n) => s * n);

最小値と最大値
   // numbers.Min()もどき
   var 最小値 = numbers.Aggregate((s, n) => Math.Min(s, n));

   // numbers.Max()もどき
   var 最大値 = numbers.Aggregate((s, n) => Math.Max(s, n));

   // 同時に求める(なんかイマイチな気がする)
   var 結果 = numbers.Select(n => new {Min = n, Max = n})
                     .Aggregate((s, n) => new {Min = Math.Min(s.Min, n.Min), Max = Math.Max(s.Max, n.Max)});

カウント
   // numbers.Count()もどき
   var 合計 = numbers.Aggregate(
                          0,                // 初期値
                          (s, _) => s + 1); // 中間計算

平均
   // numbers.Average()もどき
   var 平均 = numbers.Aggregate(
                          new {計 = 0, 数 = 0},                             // 初期値
                          (s, n) => new {計 = (s.計 + n), 数 = (s.数 + 1)}, // 中間計算
                          s => s.計 / s.数);                                // 結果処理
   // ⑩<死ぬよ
   // ②<えっ?
   // ⑩<要素数が0だと死ぬ

タグ一覧