連載:[完全版]究極のC#プログラミング

Chapter16 LINQとメソッド構文

川俣 晶
2010/03/29
Page 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

16.9 メソッド構文の複数のソースからクエリする

 クエリ式のfrom句に相当するメソッドは、メソッド構文には存在しない。列挙できるオブジェクトがクエリの起点になるのである。しかし、そうすると次のリスト16.11のようなクエリ式をメソッド構文で記述できなくなる。クエリの起点が2つあるからだ。

using System;
using System.Linq;

class Program
{
  static void Main(string[] args)
  {
    var query = from x in Enumerable.Range(1, 9)
                from y in Enumerable.Range(1, 9)
                select x + "×" + y + "=" + (x * y).ToString();

    foreach (string s in query) Console.WriteLine(s);
    // 出力:
    // 1×1=1
    // 1×2=2
    // 1×3=3
    //(中略)
    // 9×7=63
    // 9×8=72
    // 9×9=81
  }
}
リスト16.11 掛け算の九九一覧表示

 この場合、同等のクエリをメソッド構文で記述するには次のようにする。

var query = Enumerable.Range(1, 9)
              .SelectMany(
                  (x) => Enumerable.Range(1, 9),
               (x, y) => x + "×" + y + "=" + (x * y).ToString());

 この場合、2つのfrom句というクエリ式を、select句に対応するSelectメソッドの代わりに「SelectManyメソッド」を用いて実現する。このような回りくどい形を取らなければならない。しかも、この例のSelectManyメソッドの引数には2つのラムダ式を渡しており、直感的に動作がわかりやすいとはいいにくい。

 この場合のSelectManyメソッドは図16.1のように機能する。


図16.1 SelectManyメソッドの動作

 図16.1を見るとわかるとおり、2つのソースから結果を生成する機能を持っていることはわかると思うが、2つのソースのうち1つは前段階から、もう1つは引数から受け取る形式であり、直感的にはわかりにくい。

 ちなみに、この例ではSelectManyメソッドの第1引数のラムダ式の仮引数xは使用されていない。しかし、これを使用することもできる。これを使えば、次のような第2段階の列挙が第1段階で列挙された値によって変わるクエリも記述できる。

var query = Enumerable.Range(1, 3)
            .SelectMany(
                (x) => Enumerable.Range(1, x),
             (x, y) => x + "×" + y + "=" + (x * y).ToString());
// 出力:
// 1×1=1
// 2×1=2
// 2×2=4
// 3×1=3
// 3×2=6
// 3×3=9
第2段階の列挙が第1段階で列挙された値によって変わるクエリ(リスト16.11からクエリのみ差し替え)

 このように、1×……は1回しか列挙されないが3×……は3回列挙されており、回数が変化していることがわかる。これは、仮引数の値を活用したためである。


 INDEX
  [完全版]究極のC#プログラミング
  Chapter16 LINQとメソッド構文
    1.16.1 予約語のエスケープ
    2.16.2 メソッド構文のLINQ
    3.16.3 クエリ式とメソッド構文の違い
    4.16.4 絞り込みと結果の生成
    5.16.5 最初の事例の別解
    6.16.6 メソッド構文でのみ可能なクエリ
    7.16.7 メソッド構文のソート
    8.16.8 orderbyの比較オブジェクト
  9.16.9 メソッド構文の複数のソースからクエリする
    10.16.10 メソッド構文のクエリの接続
    11.16.11 クエリ結果のグループ化
    12.16.12 メソッド構文で複数のソースを関連付ける
    13.16.13 メソッド構文のグループ化結合
    14.16.14 メソッド構文の左外部結合
    15.16.15 メソッド構文のlet句/【Exercise】練習問題
 
インデックス・ページヘ  「[完全版]究極のC#プログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間