Syed Salman Raza Zaidi
Syed Salman Raza Zaidi

Reputation: 2192

Group by and Count on List

I have a list of model class with some fields in it,I want to apply group by and count on the base of ID on it,in my lst I have data like this

lst[0]=Id=10,Name="user1",Gender="Male",Course="course1";
lst[1]=Id=10,Name="user1",Gender="Male",Course="course2";
lst[2]=Id=10,Name="user1",Gender="Male",Course="course3";
lst[3]=Id=11,Name="user2",Gender="Male",Course="course4";

I want to count the course with group by on Id. This is how I am doing

var result = lst.GroupBy(n => n.Id).Select(c => new { Key = c.Key, total = c.Count()});

But after applying this I am not getting any value in result variable(ie result.Name or result[0].Name) How can I apply group by and count in this list so I get the list data after applying the group by too.

Upvotes: 0

Views: 143

Answers (3)

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

All you have to do is call ToList or ToArray.

var result = lst.GroupBy(n => n.Id)
    .Select(c => new 
    { 
        Key = c.Key, 
        total = c.Count(),
        Gender = c.First().Gender
    }).ToList();

Or alternativly - to avoid multiple iterations of the same enumeration:

var result = lst.GroupBy(n => n.Id)
    .Select(c => 
    { 
        var firstEl = c.First();
        return new {
            Key = c.Key, 
            total = c.Count(),
            Gender = firstEl.Gender,
            Name = firstEl.Name,
            Course = firstEl.Course
        }
    }).ToList();

Select will only return a query which is deferredly executed. This means you get the result when you actually iterate on the enumeration, which is enforeced by calling one of the mentioned methods.

Upvotes: 0

Felipe Oriani
Felipe Oriani

Reputation: 38598

The reason is because you are grouping by Id and just provinding an anonymous object with Key (which is the Id) and a Count. If you want to read the values, each item of the result group set will have the Count and the values where you can loop between them. For sample:

var result = lst.GroupBy(n => n.Id);

foreach (var g in result)
{
    Console.WriteLine("For group {0} the total is {1}.", g.Key, g.Count());
    foreach(var item in g)
    {
        Console.WriteLine("Name: {0}", item.Name);
    }
}

Upvotes: 1

Jamiec
Jamiec

Reputation: 136074

Having used GroupBy you have projected (Select(..)) to an anonymous object which throws away the selected items in the group; your result will be an IEnumerable<anonymous> of items with properties Key and total

var result = lst.GroupBy(n => n.Id)
                .Select(c => new { Key = c.Key, total = c.Count()});

If you want to keep the selected items, you need to include this in your projection

var result = lst.GroupBy(n => n.Id)
                .Select(c => new { Key = c.Key, total = c.Count(), Items = c});
foreach(var r in result)
{
    Console.WriteLine("Key: {0} Count:{1}",r.Key,r.total)
    foreach(var i in r.Items)
        Console.WriteLine(i.Name);
}

Upvotes: 2

Related Questions