简体   繁体   中英

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.

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);
}

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);
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM