Search code examples
c#linqcollectionsgroupinggeneric-collections

How to IEnumerable.GroupBy<T> with 3 different "qualities" getting count in C# LINQ?


I want to group by a list of objects inherited from an abstract class by:

  1. Type of item in list (in this example MyAction or MyObservation)
  2. An integer attribute ClassId
  3. A string attribute Value

And get a count out those groups.

public abstract class MyData
{
    public int ClassId;
    public string Value;
    //...
}

public class MyAction : MyData
{
    //...
}

public class MyObservation : MyData
{
    //...
}

// in some class...
IEnumerable<MyData> _myDatas;

void TryGroupBy()
{
    var result = _myDatas.GroupBy(
               data => KeySelector(data), /* ?? key is 3 pieces of info */,
               data => ElementSelector/* ?? I didn't get this either */,
               (row, rows) => new 
               {
                   ClassId = ?? /*how to get it from 3 piece key */
                   TypeOfObject = /* how to get it ?? */
                   Value = /* how to get it ?? */
                   Count = rows.Count
               }));

Solution

  • You can use an anonymous type as key and then access the properties using Key property (e.g. group.Key.Id), or you can use this overload which will give you the key as first argument of result selector:

    _myDatas.GroupBy(
               data => new { Type = data.GetType(), Id = data.ClassId, Value = data.Value },
               (key, rows) => new 
               {
                   ClassId = key.Id,
                   TypeOfObject = key.Type,
                   Value = key.Value,
                   Count = rows.Count()
               }));