C# の LINQ の基本

LINQ のクエリ演算子

LINQ は IEnumerable インターフェイスや IQueryable インターフェイスを実装したクラスからなるデータのシーケンスを、 異なるデータシーケンスに変換する作業を容易にします。

データシーケンスを作り出すメソッドをクエリ演算子 (Query operator) といいます。

C# の LINQ では多数のクエリ演算子が用意されいます。あらかじめ用意されているクエリ演算子を「標準クエリ演算子」といいます。

クエリ演算子は拡張メソッドとして実装されています。System.Linq 名前空間を参照することで、標準クエリ演算子が利用できるようになります。

LINQ の Where を用いたデータの抽出

LINQ を使って、配列からデータを抽出してみましょう。

LINQ を利用する場合には using System.Linq を書き、 System.Linq を利用できるようにします。

これにより配列に対して、 Where() メソッドが利用できるようになります。

Where() メソッドは型 T の配列に対しては、 T 型の要素を受け取り、 bool を返すデリゲートを引数にとります。

「string を受け取り bool を返すデリゲート」ということでそのまま delegate(string s) { return true; } のようにしても良いですし、 ラムダ式を使っても良いです。多くの場合ラムダ式を使う書き方が一般的なので、当サイトでもラムダ式を基本として使います。

引数のデリゲートに配列の要素がひとつずつ渡され、デリゲートが true を返す要素のみが抽出されます。

次の例では、配列 fruits の要素をひとつずつチェックして、 B で始まる要素で true を返しています。 このため、抽出結果の a"Banana" という要素だけを持つ配列になります。

using static System.Console;
using System.Linq;

partial class TestApp
{
  static void Main(string[] args)
  {
    var fruits = new string[] { "Apple", "Banana", "Orange" };
    var a = fruits.Where(elm => elm.StartsWith("B"));
    foreach (var s in a)
    {
      WriteLine($"{s}");
    }
    // Banana
  }
}

このように、 LINQ の Where クエリー演算子を用いて、元の配列からデータを抽出することができます。

LINQ の Select を用いた配列の作成

あるデータシーケンスを元にして、新しいデータシーケンスを作成するには Select クエリ演算子を使います。

JavaScript をご存知の方は map() 関数のようなものであると考えるとわかりやすいと思います。

次の例では、 fruits という配列を元にして、 idfruit というプロパティを持つオブジェクトからなる配列を作成します。

using static System.Console;
using System.Linq;

partial class TestApp
{
  static void Main(string[] args)
  {
    var i = 0;
    var fruits = new string[] { "Apple", "Banana", "Orange" };
    var a = fruits.Select(elm =>
    {
      return new
      {
        id = ++i,
        fruit = elm
      };
    });

    foreach (var s in a)
    {
      WriteLine($"{s}");
    }
  }
}

LINQ のクエリ式

LINQ の標準クエリ演算子は上の例でみた Where()Select() メソッドのように拡張メソッドとして実装されます。

この他、LINQ ではいくつかのクエリ演算子に対して、クエリ式 (Query expression) が用意されています。

クエリ式は from、 select、orderby などのキーワードで構成され SQL に似た書き方になります。

クエリ演算子のメソッドは C# のメソッドらしくパスカルケースを用いて書きますが、クエリ式は全て小文字で書きます。

上で見たデータ抽出の例をクエリ式を使って書くと,次のようになります。

using static System.Console;
using System.Linq;

partial class TestApp
{
  static void Main(string[] args)
  {
    var fruits = new string[] { "Apple", "Banana", "Orange" };
    var a = from elm in fruits
            where elm.StartsWith("B")
            select elm;
    foreach (var s in a)
    {
      WriteLine($"{s}");
    }
    // Banana
  }
}

また、上で見た Select によるシーケンスの作成は次のようになります。

using static System.Console;
using System.Linq;

partial class TestApp
{
  static void Main(string[] args)
  {
    var i = 0;
    var fruits = new string[] { "Apple", "Banana", "Orange" };
    var a = from elm in fruits
            select new
            {
              id = ++i,
              fruit = elm
            };
    foreach (var s in a)
    {
      WriteLine($"{s}");
    }
  }
}

この例のように、クエリ式でははじめに from キーワードと in キーワードを用いて、 クエリ演算子の引数として渡されるデリゲートに渡る変数と対象のシーケンスを指定します。

その後に、デリゲートの本体部分を並べて記述する形式になります。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 C# 入門