【C#】LinqのGroupByを自作クラスでグループ化

LinqのGroupBy基礎

以下のデータを「Key1」「Key2」でGroupByして、ValueをSumしてみます。

var list = new List()
{
    new SomeData() { Key1 = "1", Key2 = "1", Value = 100 },
    new SomeData() { Key1 = "1", Key2 = "1", Value = 200 },
    new SomeData() { Key1 = "2", Key2 = "1", Value = 300 },
    new SomeData() { Key1 = "2", Key2 = "1", Value = 400 },
    new SomeData() { Key1 = "2", Key2 = "2", Value = 500 },
};

GroupByに無名クラスを使ってグループ化ができます。

var summaries = list
    .GroupBy(x => new
    {
        Key1 = x.Key1,
        Key2 = x.Key2,
    })
    .Select(x =>
    {
        return new
        {
            Key1 = x.Key.Key1,
            Key2 = x.Key.Key2,
            Value = x.Sum(y => y.Value),
        };
    });

以下の結果になります。

{ Key1 = "1", Key2 = "1", Value = 300 }
{ Key1 = "2", Key2 = "1", Value = 700 }
{ Key1 = "2", Key2 = "2", Value = 500 }

Linqの自作クラスでのGroupBy

失敗編

ここからが本題です。
以下のようなクラスを定義して、これを使ってGroupByしてみます。

public class SomeGroup
{
    public string Key1 { get; set; }

    public string Key2 { get; set; }
}
var summaries = list
    .GroupBy(x => new SomeGroup
    {
        Key1 = x.Key1,
        Key2 = x.Key2,
    })
    .Select(x =>
    {
        return new
        {
            Key1 = x.Key.Key1,
            Key2 = x.Key.Key2,
            Value = x.Sum(y => y.Value),
        };
    });

これの結果は以下となり、GroupByがされません。

{ Key1 = "1", Key2 = "1", Value = 100 }
{ Key1 = "1", Key2 = "1", Value = 200 }
{ Key1 = "2", Key2 = "1", Value = 300 }
{ Key1 = "2", Key2 = "1", Value = 400 }
{ Key1 = "2", Key2 = "2", Value = 500 }

成功編

自作のclassを使ってGroupByをするには、SomeGroupにIEquatableを実装してあげる必要があります。

public class SomeGroup : IEquatable
{
    public string Key1 { get; set; }

    public string Key2 { get; set; }

    public bool Equals(SomeGroup other)
    {
        if (other is null) return false;

        return Key1 == other.Key1 && 
               Key2 == other.Key2;
    }

    public override int GetHashCode()
    {
        return (Key1, Key2).GetHashCode();
    }
}

これでSomeGroupでグループ化できるようになります。

未分類C#

Posted by ababa