Search code examples
c#linqgroup-byigrouping

Replace the Key of an IGrouping?


Is it possible to replace the Key by which an IGrouping is grouped?

I'm currently grouping by an anonymous type like this:

var groups = orders.GroupBy(o => new { o.Date.Year, o.Date.Month });

But now my grouping key is an anonymous type. I would like to replace this grouping key by a defined Type, "YearMonth", with an overridden ToString Method.

public class YearMonth
{
    public int Year { get; set; }
    public int Month { get; set; }

    public override string ToString()
    {
        return Year + "-" + Month;
    }
}

Is there any way to replace the grouping key? Or to create a new IGrouping out of the existing IGrouping with a new grouping key?


Solution

  • Well personally I would just group on the string value, since that seems to be what you really care about from the key.

    Another simple option would be to create a date representing the month by using a constant day:

    orders.GroupBy(o => new DateTime (o.Date.Year, o.Date.Month, 1))
    

    Then you have built-in value equality and string formatting.

    You could make YearMoth an immutable struct, which will also give you value-equality semantics:

    public struct YearMonth
    {
        public readonly int Year;
        public readonly int Month;
    
        public YearMonth(int year, int month)
        {
            Year = year;
            Month = month;
        }
    
        public override string ToString()
        {
            return Year + "-" + Month;
        }
    }