セージ の メモ書き

メモこそ命の恩人だ

LINQ の GroupBy してみる

以下の sampleList オブジェクトを使用して試してみる。

public class SampleClass
{
    public string Bangou { get; set; }
    public int Sedai { get; set; }
}
var sampleList = new List<SampleClass>()
{
    new SampleClass(){ Bangou = "001", Sedai = 0 },
    new SampleClass(){ Bangou = "001", Sedai = 1 },
    new SampleClass(){ Bangou = "001", Sedai = 2 },
    new SampleClass(){ Bangou = "002", Sedai = 0 },
    new SampleClass(){ Bangou = "002", Sedai = 1 },
    new SampleClass(){ Bangou = "003", Sedai = 0 },
};

GroupBy メソッド

Enumerable.GroupBy Method (System.Linq) | Microsoft Docs

  • 指定したプロパティをキーに、要素をグルーピングできる。
  • 定義はこんな感じ。IEnumerable<IGrouping<TKey, TSource>> が返る。
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
  • グルーピングした要素は Key プロパティでアクセスする。

こんな感じ。

// Bangou プロパティでグルーピングする。
var groupList = sampleList.GroupBy(x => x.Bangou);

foreach (var group in groupList)
{
    Debug.Write($"Key : {group.Key}{Environment.NewLine}");
    foreach (var x in group) Debug.Write($"    Bangou : {x.Bangou}, Sedai : {x.Sedai}{Environment.NewLine}");
}
// Key : 001
//     Bangou : 001, Sedai : 0
//     Bangou : 001, Sedai : 1
//     Bangou : 001, Sedai : 2
// Key : 002
//     Bangou : 002, Sedai : 0
//     Bangou : 002, Sedai : 1
// Key : 003
//     Bangou : 003, Sedai : 0

// Bangou プロパティでグルーピングできたことを確認した。

グループの最大値を持つ要素を取得

  • グルーピングした要素に OrderByDescending メソッドを使用する。

こんな感じ。

// Bangou プロパティでグルーピングし、
// その中で Sedai プロパティが最大値の要素を取得する。
var result = sampleList
                .GroupBy(x => x.Bangou)
                .Select(group => group.OrderByDescending(x => x.Sedai).FirstOrDefault());

foreach (var x in result) Debug.Write($"Bangou : {x.Bangou}, Sedai : {x.Sedai}{Environment.NewLine}");
// Bangou : 001, Sedai : 2
// Bangou : 002, Sedai : 1
// Bangou : 003, Sedai : 0

// 予想通りの結果が得られたことを確認。

複数キーでグルーピング

  • 複数キーでグルーピングするなら new 演算子を使う。

ここからは、以下の sampleList オブジェクトを使用して試してみる。

public class SampleClass
{
    public string Bangou { get; set; }
    public int Sedai { get; set; }
    public string Memo { get; set; }
}
var sampleList = new List<SampleClass>()
{
    new SampleClass(){ Bangou = "001", Sedai = 0, Memo = "001-0 のメモA" },
    new SampleClass(){ Bangou = "001", Sedai = 0, Memo = "001-0 のメモB" },
    new SampleClass(){ Bangou = "001", Sedai = 1, Memo = "001-1 のメモA" },
    new SampleClass(){ Bangou = "001", Sedai = 1, Memo = "001-1 のメモB" },
    new SampleClass(){ Bangou = "002", Sedai = 0, Memo = "002-0 のメモA" },
    new SampleClass(){ Bangou = "002", Sedai = 0, Memo = "002-0 のメモB" },
    new SampleClass(){ Bangou = "002", Sedai = 0, Memo = "002-0 のメモC" },
};

こんな感じ。

// Bangou + Sedai プロパティでグルーピングする。
var groupList = sampleList.GroupBy(x => new { x.Bangou, x.Sedai });

foreach (var group in groupList)
{
    Debug.Write($"Key : {group.Key.Bangou}, {group.Key.Sedai}{Environment.NewLine}");
    foreach (var x in group) Debug.Write($"    Bangou : {x.Bangou}, Sedai : {x.Sedai}, Memo : {x.Memo}{Environment.NewLine}");
}
// Key : 001, 0
//     Bangou : 001, Sedai : 0, Memo : 001-0 のメモA
//     Bangou : 001, Sedai : 0, Memo : 001-0 のメモB
// Key : 001, 1
//     Bangou : 001, Sedai : 1, Memo : 001-1 のメモA
//     Bangou : 001, Sedai : 1, Memo : 001-1 のメモB
// Key : 002, 0
//     Bangou : 002, Sedai : 0, Memo : 002-0 のメモA
//     Bangou : 002, Sedai : 0, Memo : 002-0 のメモB
//     Bangou : 002, Sedai : 0, Memo : 002-0 のメモC

// 予想通りの結果が得られたことを確認。


以上😃