fearofawhackplanet
fearofawhackplanet

Reputation: 53446

GroupBy in lambda expressions

from x in myCollection
    group x by x.Id into y
    select new { 
       Id = y.Key, 
       Quantity = y.Sum(x => x.Quantity)
    };

How would you write the above as a lambda expression? I'm stuck on the group into part.

Upvotes: 29

Views: 132341

Answers (5)

The 0bserver
The 0bserver

Reputation: 986

So, for most of the answers here, everyone seems to be dealing with getting a simple object of Id made from count of the group, and the Key itself which is group.Key.

Although thats probably the main useage of this. Didn't really satisfy my needs.

For my own case, I basically wanted to group by some object property, then fetch a specific object from that group. Here's a sample code.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        var response = new List<ResponseClass>();
            var listOfStudents = new List<Student>();
            // Insert some objects into listOfStudents object.
            listOfStudents.GroupBy(g => g.Class).ToList()
                .ForEach(g => response.Add(g.OrderByDescending(s => s.CreatedOn).Select(a =>
                new ResponseClass
                {
                    SName = a.StudentName,
                    SAge = a.Age,
                    SClass = a.Class,
                    SCreatedOn = a.CreatedOn,
                    RandomProperty = Guid.NewGuid().ToString()
                })
                .First()));

                Console.WriteLine("This compiles and should work just fine");
    }
    class Student
    {
        public string StudentName { get; set; }
        public int Age { get; set; }
        public string Class { get; set; }
        public DateTime CreatedOn { get; set; }
    }

    class ResponseClass
    {
        public string SName { get; set; }
        public int SAge { get; set; }
        public string SClass { get; set; }
        public DateTime SCreatedOn { get; set; }
        public string RandomProperty { get; set; }
    }
}

If you would rather use a foreach loop (I prefer lambda as I find it easier to read), but if you do, you could do it like so.

foreach (IGrouping<string, Student> groupedStudents in listOfStudents.GroupBy(g => g.Class))
            {
                response.Add(groupedStudents.OrderByDescending(x => x.CreatedOn).Select(a =>
                new ResponseClass
                {
                    SName = a.StudentName,
                    SAge = a.Age,
                    SClass = a.Class,
                    SCreatedOn = a.CreatedOn,
                    RandomProperty = Guid.NewGuid().ToString()
                }).First());
            }

Hope this helps someone. :)

Upvotes: -1

Drunken Code Monkey
Drunken Code Monkey

Reputation: 1836

        var mostFrequent =
            lstIn.Where(i => !string.IsNullOrEmpty(i))
                 .GroupBy(s => s)
                 .OrderByDescending(g => g.Count())
                 .Select(s => s.Key)
                 .FirstOrDefault();

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503679

Query continuations (select...into and group...into, but not join...into) are equivalent to just splitting up the query expression. So I like to think of your example as:

var tmp = from x in myCollection
          group x by x.Id;
var result = from y in tmp
             select new { 
               Id = y.Key, 
               Quantity = y.Sum(x => x.Quantity)
             };

Change those into dot notation:

var tmp = myCollection.GroupBy(x => x.Id);
var result = tmp.Select(y => new { 
               Id = y.Key, 
               Quantity = y.Sum(x => x.Quantity)
             });

Then you could combine them back:

var tmp = myCollection.GroupBy(x => x.Id)
                      .Select(y => new { 
                                Id = y.Key, 
                                Quantity = y.Sum(x => x.Quantity)
                              });

Once you work out what the C# compiler does with query expressions, the rest is relatively straightforward :)

Upvotes: 59

Femaref
Femaref

Reputation: 61497

myCollection
    .GroupBy(x => x.Id)
    .Select(x => 
        new 
        { 
          Id = x.Key, 
          Quantity = x.Sum(y => x.Quantity
        });

Upvotes: 8

LukeH
LukeH

Reputation: 269648

myCollection.GroupBy(x => x.Id)
            .Select(y => new {
                                 Id = y.Key,
                                 Quantity = y.Sum(x => x.Quantity)
                             });

Upvotes: 7

Related Questions