C#におけるLINQおよびラムダ式を使用したメモリ内リストのグループ化

C#でリストを扱うとき、特定のプロパティに基づいてアイテムをグループ化する必要があるさまざまなシナリオに直面することがあります。たとえば、Fooオブジェクトのコレクションがあり、それをBarプロパティの値に基づいて整理したいとします。ここでLINQ(Language Integrated Query)とラムダ式の力が発揮されます。このブログポストでは、これらのC#機能を使用してメモリ内リストを効果的にグループ化する方法を探ります。

問題の理解

Fooオブジェクトのリストがあり、各FooにはBarおよびLumというプロパティがあります。いくつかのFooインスタンスは同じBarの値を共有する可能性があります。あなたの目標は、これらのFooインスタンスをBarの値によってグループ化し、次にグループ化されたコレクションを反復して対応するLumの値にアクセスすることです。これにより、データの整理が向上し、特定のデータセットを操作しやすくなります。

例のシナリオ

次のFooインスタンスのリストを考えてみましょう:

var foos = new List<Foo> {
   new Foo{Bar = 1,Lum = 1},
   new Foo{Bar = 1,Lum = 2},
   new Foo{Bar = 2,Lum = 3},
};

望ましい結果

これらのFooインスタンスをBarの値によってグループ化し、最終的に次のようなものを生成したいと考えています:

  • Bar = 1: Lum = 1, Lum = 2
  • Bar = 2: Lum = 3

LINQを使用した解決策

LINQのgroup by句を使用してFooオブジェクトをグループ化できます。以下のように実現できます:

var groupedFoos = from foo in foos
                  group foo by foo.Bar into grouped
                  let lums = from g in grouped
                             select g.Lum
                  select new { Bar = grouped.Key, Lums = lums };

ステップの説明

  • Group By: group foo by foo.Barの部分は、FooインスタンスをBarプロパティに基づいてグループ化します。
  • Into Grouped: これにより、各グループの新しいスコープが作成されます。
  • Lum値の選択: let lumsステートメントは、グループ化されたオブジェクトからLum値の新しいコレクションを作成することを可能にします。
  • 最終選択: 最終的な選択は、Barの値とそれに対応するLum値のリストを含む新しいオブジェクトにすべてを組み合わせます。

ラムダ式を使用した解決策

別の方法として、ラムダ式を使用して同じ結果を達成できます。これは、より簡潔な構文を提供することができます。以下のようにします:

var groupedFoos = foos.GroupBy(x => x.Bar)
                      .Select(y => new { Bar = y.Key, Lums = y.Select(z => z.Lum) });

どのように機能するか

  • GroupBy: このメソッドは、グループ化するプロパティであるx.Barを指定するためのラムダ関数を受け取ります。
  • Select: グループ化された後、Selectを使用して各グループのために新しい匿名オブジェクトを作成し、Barとそれに対応するLum値を含みます。

グループ化されたデータを反復処理する

LINQでもラムダ式でも、グループ化されたデータを反復処理する方法は同じです。各グループをループしてLumの値を表示することができます。以下はその方法です:

foreach (var group in groupedFoos)
{
    Console.WriteLine("Lums for Bar#" + group.Bar);
    foreach (var lum in group.Lums)
    {
        Console.WriteLine(lum);
    }
}

出力は次のようになります:

Lums for Bar#1
1
2
Lums for Bar#2
3

結論

C#におけるLINQまたはラムダ式を使用したメモリ内リストのグループ化は、データを整理するための強力な方法です。LINQ構文の読みやすさとラムダ式の簡潔さのいずれを好むにせよ、どちらのアプローチもデータの希望するグループ化を効果的に達成することを可能にします。

LINQの理解を深めたい方は、101 LINQサンプルを探索して、より包括的な例を考えてみてください。

C#でデータをグループ化する経験について質問がある場合や共有したいことがあれば、お気軽に下にコメントを残してください!